lib/schemacop/v3/hash_node.rb in schemacop-3.0.0.rc1 vs lib/schemacop/v3/hash_node.rb in schemacop-3.0.0.rc2

- old
+ new

@@ -89,32 +89,41 @@ def _validate(data, result: Result.new) super_data = super return if super_data.nil? + original_data_hash = super_data.dup + data_hash = super_data.with_indifferent_access + + if original_data_hash.size != data_hash.size + ambiguous_properties = original_data_hash.keys - data_hash.keys + + result.error "Has #{ambiguous_properties.size} ambiguous properties: #{ambiguous_properties}." + end + # Validate min_properties # - if options[:min_properties] && super_data.size < options[:min_properties] - result.error "Has #{super_data.size} properties but needs at least #{options[:min_properties]}." + if options[:min_properties] && data_hash.size < options[:min_properties] + result.error "Has #{data_hash.size} properties but needs at least #{options[:min_properties]}." end # Validate max_properties # - if options[:max_properties] && super_data.size > options[:max_properties] - result.error "Has #{super_data.size} properties but needs at most #{options[:max_properties]}." + if options[:max_properties] && data_hash.size > options[:max_properties] + result.error "Has #{data_hash.size} properties but needs at most #{options[:max_properties]}." end # Validate specified properties # @properties.each_value do |node| result.in_path(node.name) do next if node.name.is_a?(Regexp) - node._validate(super_data[node.name], result: result) + node._validate(data_hash[node.name], result: result) end end # Validate additional properties # specified_properties = @properties.keys.to_set - additional_properties = super_data.reject { |k, _v| specified_properties.include?(k.to_s.to_sym) } + additional_properties = data_hash.reject { |k, _v| specified_properties.include?(k.to_s) } property_patterns = {} @properties.each_value do |property| if property.name.is_a?(Regexp) @@ -147,11 +156,11 @@ end # Validate dependencies # options[:dependencies]&.each do |source, targets| targets.each do |target| - if super_data[source].present? && super_data[target].blank? + if data_hash[source].present? && data_hash[target].blank? result.error "Missing property #{target.to_s.inspect} because #{source.to_s.inspect} is given." end end end end @@ -159,32 +168,41 @@ def children @properties.values end def cast(data) - result = {} + result = {}.with_indifferent_access data ||= default return nil if data.nil? + original_data_hash = data.dup + data_hash = data.with_indifferent_access + + if original_data_hash.size != data_hash.size + ambiguous_properties = original_data_hash.keys - data_hash.keys + + result.error "Has #{ambiguous_properties.size} ambiguous properties: #{ambiguous_properties}." + end + property_patterns = {} @properties.each_value do |prop| if prop.name.is_a?(Regexp) property_patterns[prop.name] = prop next end - result[prop.name] = prop.cast(data[prop.name]) + result[prop.name] = prop.cast(data_hash[prop.name]) - if result[prop.name].nil? && !data.include?(prop.name) + if result[prop.name].nil? && !data_hash.include?(prop.name) result.delete(prop.name) end end # Handle regex properties specified_properties = @properties.keys.to_set - additional_properties = data.reject { |k, _v| specified_properties.include?(k.to_s.to_sym) } + additional_properties = data_hash.reject { |k, _v| specified_properties.include?(k.to_s.to_sym) } if additional_properties.any? && property_patterns.any? additional_properties.each do |name, additional_property| match_key = property_patterns.keys.find { |p| p.match?(name.to_s) } match = property_patterns[match_key] @@ -192,13 +210,13 @@ end end # Handle additional properties if options[:additional_properties] == true - result = data.merge(result) + result = data_hash.merge(result) elsif options[:additional_properties].is_a?(Node) specified_properties = @properties.keys.to_set - additional_properties = data.reject { |k, _v| specified_properties.include?(k.to_s.to_sym) } + additional_properties = data_hash.reject { |k, _v| specified_properties.include?(k.to_s.to_sym) } if additional_properties.any? additional_properties_result = {} additional_properties.each do |key, value| additional_properties_result[key] = options[:additional_properties].cast(value) end