A library for defining and validating data structures.
A SignatureContract defines a parameters object for a ParametersContract.
NEGATED_TYPE
= 'stannum.constraints.valid'
The :type of the error generated for a matching object.
TYPE
= 'stannum.constraints.invalid'
The :type of the error generated for a non-matching object.
#initialize(**options) => SignatureContract
#options => Hash<Symbol, Object>
#==(other) => true, false
Performs an equality comparison.
#add_constraint(constraint, property: nil, sanity: false, **options) => self
Adds a constraint to the contract.
When the contract is matched with an object, the constraint will be evaluated with the object and the errors updated accordingly.
If the :property option is set, this defines a property constraint. See #add_property_constraint for more information.
#add_key_constraint(key, constraint, sanity: false, **options) => self
Adds a key constraint to the contract.
When the contract is called, the contract will find the value of the object for the given key.
#add_property_constraint(property, constraint, sanity: false, **options) => self
Adds a property constraint to the contract.
When the contract is called, the contract will find the value of that property for the given object. If the property is an array, the contract will recursively retrieve each property.
A property of nil will match against the given object itself, rather than one of its properties.
If the value does not match the constraint, then the error from the constraint will be added in an error namespace matching the constraint. For example, a property of :name will add the error message to errors.dig(:name), while a property of [:manufacturer, :address, :street] will add the error message to errors.dig(:manufacturer, :address, :street).
#allow_extra_keys? => true, false
#clone(freeze: nil) => Stannum::Constraints::Base
Produces a shallow copy of the constraint.
#concat(other) => Stannum::Contract
Concatenate the constraints from the given other contract.
Merges the constraints from the concatenated contract into the original. This is a dynamic process - if constraints are added to the concatenated contract at a later point, they will also be added to the original. This is also recursive - concatenating a contract will also merge the constraints from any contracts that were themselves concatenated in the concatenated contract.
There are two approaches for adding one contract to another. The first and simplest is to take advantage of the fact that each contract is, itself, a constraint. Adding the new contract to the original via #add_constraint works in most cases - the new contract will be called during #matches? and when generating errors. However, functionality that inspects the constraints directly (such as the :allow_extra_keys functionality in HashContract) will fail.
Concatenating a contract in another is a much closer relationship. Each time the constraints on the original contract are enumerated, it will also yield the constraints from the concatenated contract (and from any contracts that are concatenated in that contract, recursively).
To sum up, use #add_constraint when you want to constrain a property of the actual object with a contract. Use #concat when you want to add more constraints about the object itself.
Concatenating A Contract
concatenated_contract = Stannum::Contract.new
.add_constraint(Stannum::Constraint.new { |int| int < 10 })
original_contract = Stannum::Contract.new
.add_constraint(Stannum::Constraint.new { |int| int >= 0 })
.concat(concatenated_contract)
original_contract.matches?(-1) #=> a failing result
original_contract.matches?(0) #=> a passing result
original_contract.matches?(5) #=> a passing result
original_contract.matches?(10) #=> a failing result
#does_not_match?(actual) => true, false
Checks that none of the added constraints match the object.
If the contract defines sanity constraints, the sanity constraints will be matched first. If any of the sanity constraints fail (#does_not_match? for the constraint returns true), then this method will immediately return true and all subsequent constraints will be skipped.
#dup => Stannum::Constraints::Base
Produces a shallow copy of the constraint.
#each_constraint => Enumerator
#each_constraint => Object
Iterates through the constraints defined for the contract.
Any constraints defined on concatenated contracts are yielded, followed by any constraints defined on the contract itself.
Each constraint is represented as a Stannum::Contracts::Definition, which encapsulates the constraint, the original contract, and the options specified by #add_constraint.
If the contract defines sanity constraints, the sanity constraints will be returned or yielded first, followed by the remaining constraints.
#each_constraint => Enumerator
#each_constraint => Object
#each_pair(actual) => Enumerator
#each_pair(actual) => Object
Iterates through the constraints and mapped values.
For each constraint defined for the contract, the contract defines a data mapping representing the object or property that the constraint will match. Calling #each_pair for an object yields the constraint and the mapped object or property for that constraint and object.
If the contract defines sanity constraints, the sanity constraints will be returned or yielded first, followed by the remaining constraints.
By default, this mapping returns the object itself; however, this can be overriden in subclasses based on the constraint options, such as matching constraints against the properties of an object rather than the object itself.
This enumerator is used internally to implement the Constraint interface for subclasses of Contract.
#each_pair(actual) => Enumerator
#each_pair(actual) => Object
#errors_for(actual, errors: nil) => Stannum::Errors
Aggregates errors for each constraint that does not match the object.
For each defined constraint, the constraint is matched against the mapped value for that constraint and the object. If the constraint does not match the mapped value, the corresponding errors will be added to the errors object.
If the contract defines sanity constraints, the sanity constraints will be matched first. If any of the sanity constraints fail, #errors_for will immediately return the errors for the failed constraint.
#expected_keys => Array
#key_type => Stannum::Constraints::Base, Class, nil
#match(actual) => Array<Boolean, Stannum::Errors>
Matches and generates errors for each constraint.
For each defined constraint, the constraint is matched against the mapped value for that constraint and the object. If the constraint does not match the mapped value, the corresponding errors will be added to the errors object.
Finally, if all of the constraints match the mapped value, #match will return true and the errors object. Otherwise, #match will return false and the errors object.
If the contract defines sanity constraints, the sanity constraints will be matched first. If any of the sanity constraints fail (#matches? for the constraint returns false), then this method will immediately return false and the errors for the failed sanity constraint; and all subsequent constraints will be skipped.
#matches?(actual) => true, false
Also known as:
match?
Checks that all of the added constraints match the object.
If the contract defines sanity constraints, the sanity constraints will be matched first. If any of the sanity constraints fail (#does_not_match? for the constraint returns true), then this method will immediately return false and all subsequent constraints will be skipped.
#message => String, nil
#negated_errors_for(actual, errors: nil) => Stannum::Errors
Aggregates errors for each constraint that matches the object.
For each defined constraint, the constraint is matched against the mapped value for that constraint and the object. If the constraint matches the mapped value, the corresponding errors will be added to the errors object.
If the contract defines sanity constraints, the sanity constraints will be matched first. If any of the sanity constraints fail, #errors_for will immediately return any errors already added to the errors object.
#negated_match(actual) => Array<Boolean, Stannum::Errors>
Matches and generates errors for each constraint.
For each defined constraint, the constraint is matched against the mapped value for that constraint and the object. If the constraint matches the mapped value, the corresponding errors will be added to the errors object.
Finally, if none of the constraints match the mapped value, #match will return true and the errors object. Otherwise, #match will return false and the errors object.
If the contract defines sanity constraints, the sanity constraints will be matched first. If any of the sanity constraints fail (#does_not_match? for the constraint returns true), then this method will immediately return true and any errors already set; and all subsequent constraints will be skipped.
#negated_message => String, nil
#negated_type => String
#type => String
#value_type => Stannum::Constraints::Base, Class, nil
#with_options(**options) => Object
Back to Documentation | Reference | Stannum | Stannum::Contracts | Stannum::Contracts::Parameters