Class: MSFL::Validators::Semantic
- Inherits:
-
Object
- Object
- MSFL::Validators::Semantic
- Includes:
- Definitions::HashKey
- Defined in:
- lib/msfl/validators/semantic.rb
Constant Summary collapse
- BOOLEAN_OPERATORS =
[:and, :or]
- ENUMERATION_OPERATORS =
[:in]
Instance Attribute Summary collapse
-
#current_field ⇒ Object
Returns the value of attribute current_field.
-
#current_operator ⇒ Object
Returns the value of attribute current_operator.
-
#dataset ⇒ Object
Returns the value of attribute dataset.
-
#errors ⇒ Object
Returns the value of attribute errors.
Instance Method Summary collapse
-
#initialize(dataset = nil, opts = {}) ⇒ Semantic
constructor
Used for creating new semantic validator instances.
-
#validate(hash, errors = [], opts = {}) ⇒ Object
Returns true if the object is valid, false if the object is invalid An array of hashes of errors is available at #errors.
-
#validate_boolean_set(set, errors, opts) ⇒ Array
Returns the result of merging errors with any newly encountered errors found in validating the set.
-
#validate_enumeration_set(set, errors, opts) ⇒ Object
Validates a set of enumerationd scalar values.
-
#validate_hash(hash, errors, opts) ⇒ Array
Returns the result of merging errors with any newly encountered errors found in validating the hash.
-
#validate_set(set, errors, opts) ⇒ Array
Acts as a helper method that forwards validation requests for sets to the right handler based on the :parent_operator option’s value.
Methods included from Definitions::HashKey
#all_logical_operators?, #all_operators?, #any_operators?, #binary_operators, #foreign_operators, #hash_key_operators, #logical_operators, #operator?, #partial_operators, #valid_hash_key?, #valid_hash_keys
Constructor Details
#initialize(dataset = nil, opts = {}) ⇒ Semantic
Used for creating new semantic validator instances
If the dataset argument is specified it will be used as the dataset for the validator. Otherwise the instance’s dataset will default to the first value in MSFL.configuration.datasets, unless it is empty, in which case it will revert to MSFL::Datasets::Base, which will deliberately break execution when #validate is called on the validator instance, raising a NoMethodError.
23 24 25 26 27 28 29 |
# File 'lib/msfl/validators/semantic.rb', line 23 def initialize(dataset = nil, opts = {}) @dataset = dataset unless dataset.nil? @dataset ||= MSFL.configuration.datasets.first.new unless MSFL.configuration.datasets.empty? @dataset ||= Datasets::Base.new @current_field = nil @current_operator = nil end |
Instance Attribute Details
#current_field ⇒ Object
Returns the value of attribute current_field.
9 10 11 |
# File 'lib/msfl/validators/semantic.rb', line 9 def current_field @current_field end |
#current_operator ⇒ Object
Returns the value of attribute current_operator.
9 10 11 |
# File 'lib/msfl/validators/semantic.rb', line 9 def current_operator @current_operator end |
#dataset ⇒ Object
Returns the value of attribute dataset.
9 10 11 |
# File 'lib/msfl/validators/semantic.rb', line 9 def dataset @dataset end |
#errors ⇒ Object
Returns the value of attribute errors.
9 10 11 |
# File 'lib/msfl/validators/semantic.rb', line 9 def errors @errors end |
Instance Method Details
#validate(hash, errors = [], opts = {}) ⇒ Object
Returns true if the object is valid, false if the object is invalid An array of hashes of errors is available at #errors
This method is not meant to be called recursively, the private method recursive_validate is used
for this purpose
40 41 42 43 44 45 46 47 |
# File 'lib/msfl/validators/semantic.rb', line 40 def validate(hash, errors = [], opts = {}) errors << "Object to validate must be a Hash" unless hash.is_a?(Hash) recursive_validate hash, errors, opts @errors = errors result = true if @errors.empty? result ||= false result end |
#validate_boolean_set(set, errors, opts) ⇒ Array
Returns the result of merging errors with any newly encountered errors found in validating the set
120 121 122 123 124 125 126 127 128 |
# File 'lib/msfl/validators/semantic.rb', line 120 def validate_boolean_set(set, errors, opts) # Every member needs to be a hash set.each do |value| errors << "Every member of a boolean set must be a Hash" unless value.is_a?(Hash) # recursively call validate on each member recursive_validate value, errors, opts end errors end |
#validate_enumeration_set(set, errors, opts) ⇒ Object
Validates a set of enumerationd scalar values
131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/msfl/validators/semantic.rb', line 131 def validate_enumeration_set(set, errors, opts) current_field = opts[:parent_field] if opts.has_key?(:parent_field) current_field ||= nil errors << "Validate enumeration set requires the parent_field option to be set" if current_field.nil? set.each do |value| # this isn't quite right, it feels dirty to use :each errors << "No members of an enumeration set may permit iteration across itself" if value.respond_to?(:each) dataset.validate_type_conforms value, current_field, errors dataset.validate_value_conforms value, current_field, errors end errors end |
#validate_hash(hash, errors, opts) ⇒ Array
Returns the result of merging errors with any newly encountered errors found in validating the hash
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/msfl/validators/semantic.rb', line 55 def validate_hash(hash, errors, opts) # set current field current_field = nil # validate the keys and values hash.each do |k, value| key = k.to_sym # validate the current hash key using broad hash key validation errors << "Hash key encountered that is broadly invalid." unless valid_hash_key?(key) # validate that the hash key is supported as an operator or dataset field # if they key is an operator validate the dataset supports the operator for the current field # # if the key is a field of the dataset then we need to validate that the _value_ conforms to the dataset # specific validation rules for that field # # if they key is neither an operator nor a field we raise an ArgumentError # # Then make a recursive call to validate on the value so that it and its elements are validated # later I might be able to optimize this by only making the recursive call for Sets and Hashes # if dataset.has_operator? key dataset.validate_operator_conforms key, current_field, errors opts[:parent_operator] = key elsif dataset.has_field? key current_field = key dataset.validate_type_conforms value, current_field, errors dataset.validate_value_conforms value, current_field, errors opts[:parent_field] = current_field else errors << "Encountered hash key that is neither an operator nor a property of the dataset" end recursive_validate value, errors, opts end errors end |
#validate_set(set, errors, opts) ⇒ Array
Acts as a helper method that forwards validation requests for sets to the right handler based on the
:parent_operator option's value
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/msfl/validators/semantic.rb', line 99 def validate_set(set, errors, opts) = "Validate set requires the :parent_operator option be set and represented in either the BOOLEAN_OPERATORS or ENUMERATION_OPERATORS constant" errors << unless opts.has_key?(:parent_operator) if BOOLEAN_OPERATORS.include?(opts[:parent_operator]) validate_boolean_set set, errors, opts elsif ENUMERATION_OPERATORS.include?(opts[:parent_operator]) validate_enumeration_set set, errors, opts else errors << end errors end |