json-schema 2.4.1 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +6 -14
 - data/README.textile +58 -7
 - data/lib/json-schema.rb +3 -1
 - data/lib/json-schema/attributes/additionalitems.rb +14 -11
 - data/lib/json-schema/attributes/additionalproperties.rb +33 -43
 - data/lib/json-schema/attributes/anyof.rb +4 -0
 - data/lib/json-schema/attributes/dependencies.rb +31 -19
 - data/lib/json-schema/attributes/disallow.rb +2 -3
 - data/lib/json-schema/attributes/divisibleby.rb +11 -7
 - data/lib/json-schema/attributes/enum.rb +14 -16
 - data/lib/json-schema/attributes/format.rb +4 -7
 - data/lib/json-schema/attributes/formats/date_time_v4.rb +5 -8
 - data/lib/json-schema/attributes/formats/ip.rb +41 -0
 - data/lib/json-schema/attributes/formats/uri.rb +10 -8
 - data/lib/json-schema/attributes/items.rb +15 -16
 - data/lib/json-schema/attributes/limit.rb +179 -0
 - data/lib/json-schema/attributes/maxdecimal.rb +7 -6
 - data/lib/json-schema/attributes/multipleof.rb +4 -11
 - data/lib/json-schema/attributes/not.rb +1 -1
 - data/lib/json-schema/attributes/oneof.rb +15 -6
 - data/lib/json-schema/attributes/pattern.rb +7 -6
 - data/lib/json-schema/attributes/patternproperties.rb +9 -12
 - data/lib/json-schema/attributes/properties.rb +55 -39
 - data/lib/json-schema/attributes/properties_optional.rb +13 -12
 - data/lib/json-schema/attributes/ref.rb +4 -4
 - data/lib/json-schema/attributes/required.rb +16 -13
 - data/lib/json-schema/attributes/type.rb +13 -18
 - data/lib/json-schema/attributes/type_v4.rb +11 -18
 - data/lib/json-schema/attributes/uniqueitems.rb +5 -7
 - data/lib/json-schema/schema.rb +8 -8
 - data/lib/json-schema/schema/#validator.rb# +37 -0
 - data/lib/json-schema/schema/reader.rb +113 -0
 - data/lib/json-schema/util/uri.rb +16 -0
 - data/lib/json-schema/validator.rb +123 -128
 - data/lib/json-schema/validators/draft1.rb +1 -1
 - data/lib/json-schema/validators/draft2.rb +1 -1
 - data/lib/json-schema/validators/draft3.rb +1 -1
 - data/lib/json-schema/validators/draft4.rb +1 -1
 - data/lib/json-schema/validators/hyper-draft4.rb +1 -1
 - data/test/schemas/address_microformat.json +18 -0
 - data/test/schemas/definition_schema.json +15 -0
 - data/test/schemas/ref john with spaces schema.json +11 -0
 - data/test/schemas/relative_definition_schema.json +8 -0
 - data/test/test_all_of_ref_schema.rb +12 -15
 - data/test/test_any_of_ref_schema.rb +7 -9
 - data/test/test_bad_schema_ref.rb +18 -12
 - data/test/test_common_test_suite.rb +45 -29
 - data/test/test_custom_format.rb +2 -3
 - data/test/test_definition.rb +15 -0
 - data/test/test_extended_schema.rb +25 -31
 - data/test/test_extends_and_additionalProperties.rb +23 -21
 - data/test/test_files_v3.rb +14 -23
 - data/test/test_fragment_resolution.rb +6 -7
 - data/test/test_fragment_validation_with_ref.rb +2 -8
 - data/test/test_full_validation.rb +2 -3
 - data/test/test_helper.rb +46 -1
 - data/test/test_initialize_data.rb +118 -0
 - data/test/test_jsonschema_draft1.rb +48 -600
 - data/test/test_jsonschema_draft2.rb +48 -699
 - data/test/test_jsonschema_draft3.rb +91 -861
 - data/test/test_jsonschema_draft4.rb +173 -812
 - data/test/test_list_option.rb +6 -7
 - data/test/{test_merge_misisng_values.rb → test_merge_missing_values.rb} +2 -3
 - data/test/test_minitems.rb +2 -4
 - data/test/test_one_of.rb +9 -19
 - data/test/test_ruby_schema.rb +5 -14
 - data/test/test_schema_loader.rb +74 -0
 - data/test/test_schema_type_attribute.rb +2 -3
 - data/test/test_schema_validation.rb +4 -5
 - data/test/test_stringify.rb +2 -3
 - data/test/test_uri_related.rb +67 -0
 - data/test/test_validator.rb +53 -0
 - metadata +129 -51
 - data/lib/json-schema/attributes/dependencies_v4.rb +0 -27
 - data/lib/json-schema/attributes/formats/ip4.rb +0 -20
 - data/lib/json-schema/attributes/formats/ip6.rb +0 -20
 - data/lib/json-schema/attributes/maximum.rb +0 -17
 - data/lib/json-schema/attributes/maximum_inclusive.rb +0 -17
 - data/lib/json-schema/attributes/maxitems.rb +0 -14
 - data/lib/json-schema/attributes/maxlength.rb +0 -16
 - data/lib/json-schema/attributes/maxproperties.rb +0 -14
 - data/lib/json-schema/attributes/minimum.rb +0 -17
 - data/lib/json-schema/attributes/minimum_inclusive.rb +0 -17
 - data/lib/json-schema/attributes/minitems.rb +0 -14
 - data/lib/json-schema/attributes/minlength.rb +0 -16
 - data/lib/json-schema/attributes/minproperties.rb +0 -14
 - data/lib/json-schema/attributes/properties_v4.rb +0 -58
 - data/lib/json-schema/uri/file.rb +0 -36
 
| 
         @@ -0,0 +1,41 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'json-schema/attributes/format'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'ipaddr'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'socket'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module JSON
         
     | 
| 
      
 6 
     | 
    
         
            +
              class Schema
         
     | 
| 
      
 7 
     | 
    
         
            +
                class IPFormat < FormatAttribute
         
     | 
| 
      
 8 
     | 
    
         
            +
                  def self.validate(current_schema, data, fragments, processor, validator, options = {})
         
     | 
| 
      
 9 
     | 
    
         
            +
                    return unless data.is_a?(String)
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 12 
     | 
    
         
            +
                      ip = IPAddr.new(data)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    rescue ArgumentError => e
         
     | 
| 
      
 14 
     | 
    
         
            +
                      raise e unless e.message == 'invalid address'
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                    family = ip_version == 6 ? Socket::AF_INET6 : Socket::AF_INET
         
     | 
| 
      
 18 
     | 
    
         
            +
                    unless ip && ip.family == family
         
     | 
| 
      
 19 
     | 
    
         
            +
                      error_message = "The property '#{build_fragment(fragments)}' must be a valid IPv#{ip_version} address"
         
     | 
| 
      
 20 
     | 
    
         
            +
                      validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
         
     | 
| 
      
 21 
     | 
    
         
            +
                    end
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  def self.ip_version
         
     | 
| 
      
 25 
     | 
    
         
            +
                    raise NotImplementedError
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                class IP4Format < IPFormat
         
     | 
| 
      
 30 
     | 
    
         
            +
                  def self.ip_version
         
     | 
| 
      
 31 
     | 
    
         
            +
                    4
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                class IP6Format < IPFormat
         
     | 
| 
      
 36 
     | 
    
         
            +
                  def self.ip_version
         
     | 
| 
      
 37 
     | 
    
         
            +
                    6
         
     | 
| 
      
 38 
     | 
    
         
            +
                  end
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,16 +1,18 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require 'json-schema/attribute'
         
     | 
| 
       2 
     | 
    
         
            -
            require 'uri'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'addressable/uri'
         
     | 
| 
       3 
3 
     | 
    
         
             
            module JSON
         
     | 
| 
       4 
4 
     | 
    
         
             
              class Schema
         
     | 
| 
       5 
5 
     | 
    
         
             
                class UriFormat < FormatAttribute
         
     | 
| 
       6 
6 
     | 
    
         
             
                  def self.validate(current_schema, data, fragments, processor, validator, options = {})
         
     | 
| 
       7 
     | 
    
         
            -
                     
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
                       
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
                       
     | 
| 
      
 7 
     | 
    
         
            +
                    return unless data.is_a?(String)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    error_message = "The property '#{build_fragment(fragments)}' must be a valid URI"
         
     | 
| 
      
 9 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 10 
     | 
    
         
            +
                      # TODO
         
     | 
| 
      
 11 
     | 
    
         
            +
                      # Addressable only throws an exception on to_s for invalid URI strings, although it
         
     | 
| 
      
 12 
     | 
    
         
            +
                      # probably should throughout parse already - https://github.com/sporkmonger/addressable/issues/177
         
     | 
| 
      
 13 
     | 
    
         
            +
                      Addressable::URI.parse(data).to_s
         
     | 
| 
      
 14 
     | 
    
         
            +
                    rescue Addressable::URI::InvalidURIError
         
     | 
| 
      
 15 
     | 
    
         
            +
                      validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
         
     | 
| 
       14 
16 
     | 
    
         
             
                    end
         
     | 
| 
       15 
17 
     | 
    
         
             
                  end
         
     | 
| 
       16 
18 
     | 
    
         
             
                end
         
     | 
| 
         @@ -4,22 +4,21 @@ module JSON 
     | 
|
| 
       4 
4 
     | 
    
         
             
              class Schema
         
     | 
| 
       5 
5 
     | 
    
         
             
                class ItemsAttribute < Attribute
         
     | 
| 
       6 
6 
     | 
    
         
             
                  def self.validate(current_schema, data, fragments, processor, validator, options = {})
         
     | 
| 
       7 
     | 
    
         
            -
                     
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                       end
         
     | 
| 
      
 7 
     | 
    
         
            +
                    return unless data.is_a?(Array)
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                    items = current_schema.schema['items']
         
     | 
| 
      
 10 
     | 
    
         
            +
                    case items
         
     | 
| 
      
 11 
     | 
    
         
            +
                    when Hash
         
     | 
| 
      
 12 
     | 
    
         
            +
                      schema = JSON::Schema.new(items, current_schema.uri, validator)
         
     | 
| 
      
 13 
     | 
    
         
            +
                      data.each_with_index do |item, i|
         
     | 
| 
      
 14 
     | 
    
         
            +
                        schema.validate(item, fragments + [i.to_s], processor, options)
         
     | 
| 
      
 15 
     | 
    
         
            +
                      end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                    when Array
         
     | 
| 
      
 18 
     | 
    
         
            +
                      items.each_with_index do |item_schema, i|
         
     | 
| 
      
 19 
     | 
    
         
            +
                        schema = JSON::Schema.new(item_schema, current_schema.uri, validator)
         
     | 
| 
      
 20 
     | 
    
         
            +
                        schema.validate(data[i], fragments + [i.to_s], processor, options)
         
     | 
| 
      
 21 
     | 
    
         
            +
                      end
         
     | 
| 
       23 
22 
     | 
    
         
             
                    end
         
     | 
| 
       24 
23 
     | 
    
         
             
                  end
         
     | 
| 
       25 
24 
     | 
    
         
             
                end
         
     | 
| 
         @@ -0,0 +1,179 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'json-schema/attribute'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module JSON
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Schema
         
     | 
| 
      
 5 
     | 
    
         
            +
                class LimitAttribute < Attribute
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def self.validate(current_schema, data, fragments, processor, validator, options = {})
         
     | 
| 
      
 7 
     | 
    
         
            +
                    schema = current_schema.schema
         
     | 
| 
      
 8 
     | 
    
         
            +
                    return unless data.is_a?(acceptable_type) && invalid?(schema, value(data))
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                    property    = build_fragment(fragments)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    description = error_message(schema)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    message = format("The property '%s' %s", property, description)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  def self.invalid?(schema, data)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    exclusive = exclusive?(schema)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    limit = limit(schema)
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                    if limit_name.start_with?('max')
         
     | 
| 
      
 21 
     | 
    
         
            +
                      exclusive ? data >= limit : data > limit
         
     | 
| 
      
 22 
     | 
    
         
            +
                    else
         
     | 
| 
      
 23 
     | 
    
         
            +
                      exclusive ? data <= limit : data < limit
         
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  def self.limit(schema)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    schema[limit_name]
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  def self.exclusive?(schema)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    false
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  def self.value(data)
         
     | 
| 
      
 36 
     | 
    
         
            +
                    data
         
     | 
| 
      
 37 
     | 
    
         
            +
                  end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                  def self.acceptable_type
         
     | 
| 
      
 40 
     | 
    
         
            +
                    raise NotImplementedError
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                  def self.error_message(schema)
         
     | 
| 
      
 44 
     | 
    
         
            +
                    raise NotImplementedError
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                  def self.limit_name
         
     | 
| 
      
 48 
     | 
    
         
            +
                    raise NotImplementedError
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                class MinLengthAttribute < LimitAttribute
         
     | 
| 
      
 53 
     | 
    
         
            +
                  def self.acceptable_type
         
     | 
| 
      
 54 
     | 
    
         
            +
                    String
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  def self.limit_name
         
     | 
| 
      
 58 
     | 
    
         
            +
                    'minLength'
         
     | 
| 
      
 59 
     | 
    
         
            +
                  end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                  def self.error_message(schema)
         
     | 
| 
      
 62 
     | 
    
         
            +
                    "was not of a minimum string length of #{limit(schema)}"
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  def self.value(data)
         
     | 
| 
      
 66 
     | 
    
         
            +
                    data.length
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
      
 68 
     | 
    
         
            +
                end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                class MaxLengthAttribute < MinLengthAttribute
         
     | 
| 
      
 71 
     | 
    
         
            +
                  def self.limit_name
         
     | 
| 
      
 72 
     | 
    
         
            +
                    'maxLength'
         
     | 
| 
      
 73 
     | 
    
         
            +
                  end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                  def self.error_message(schema)
         
     | 
| 
      
 76 
     | 
    
         
            +
                    "was not of a maximum string length of #{limit(schema)}"
         
     | 
| 
      
 77 
     | 
    
         
            +
                  end
         
     | 
| 
      
 78 
     | 
    
         
            +
                end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                class MinItemsAttribute < LimitAttribute
         
     | 
| 
      
 81 
     | 
    
         
            +
                  def self.acceptable_type
         
     | 
| 
      
 82 
     | 
    
         
            +
                    Array
         
     | 
| 
      
 83 
     | 
    
         
            +
                  end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                  def self.value(data)
         
     | 
| 
      
 86 
     | 
    
         
            +
                    data.length
         
     | 
| 
      
 87 
     | 
    
         
            +
                  end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                  def self.limit_name
         
     | 
| 
      
 90 
     | 
    
         
            +
                    'minItems'
         
     | 
| 
      
 91 
     | 
    
         
            +
                  end
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                  def self.error_message(schema)
         
     | 
| 
      
 94 
     | 
    
         
            +
                    "did not contain a minimum number of items #{limit(schema)}"
         
     | 
| 
      
 95 
     | 
    
         
            +
                  end
         
     | 
| 
      
 96 
     | 
    
         
            +
                end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                class MaxItemsAttribute < MinItemsAttribute
         
     | 
| 
      
 99 
     | 
    
         
            +
                  def self.limit_name
         
     | 
| 
      
 100 
     | 
    
         
            +
                    'maxItems'
         
     | 
| 
      
 101 
     | 
    
         
            +
                  end
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                  def self.error_message(schema)
         
     | 
| 
      
 104 
     | 
    
         
            +
                    "had more items than the allowed #{limit(schema)}"
         
     | 
| 
      
 105 
     | 
    
         
            +
                  end
         
     | 
| 
      
 106 
     | 
    
         
            +
                end
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
                class MinPropertiesAttribute < LimitAttribute
         
     | 
| 
      
 109 
     | 
    
         
            +
                  def self.acceptable_type
         
     | 
| 
      
 110 
     | 
    
         
            +
                    Hash
         
     | 
| 
      
 111 
     | 
    
         
            +
                  end
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                  def self.value(data)
         
     | 
| 
      
 114 
     | 
    
         
            +
                    data.size
         
     | 
| 
      
 115 
     | 
    
         
            +
                  end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                  def self.limit_name
         
     | 
| 
      
 118 
     | 
    
         
            +
                    'minProperties'
         
     | 
| 
      
 119 
     | 
    
         
            +
                  end
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                  def self.error_message(schema)
         
     | 
| 
      
 122 
     | 
    
         
            +
                    "did not contain a minimum number of properties #{limit(schema)}"
         
     | 
| 
      
 123 
     | 
    
         
            +
                  end
         
     | 
| 
      
 124 
     | 
    
         
            +
                end
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
                class MaxPropertiesAttribute < MinPropertiesAttribute
         
     | 
| 
      
 127 
     | 
    
         
            +
                  def self.limit_name
         
     | 
| 
      
 128 
     | 
    
         
            +
                    'maxProperties'
         
     | 
| 
      
 129 
     | 
    
         
            +
                  end
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
                  def self.error_message(schema)
         
     | 
| 
      
 132 
     | 
    
         
            +
                    "had more properties than the allowed #{limit(schema)}"
         
     | 
| 
      
 133 
     | 
    
         
            +
                  end
         
     | 
| 
      
 134 
     | 
    
         
            +
                end
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                class NumericLimitAttribute < LimitAttribute
         
     | 
| 
      
 137 
     | 
    
         
            +
                  def self.acceptable_type
         
     | 
| 
      
 138 
     | 
    
         
            +
                    Numeric
         
     | 
| 
      
 139 
     | 
    
         
            +
                  end
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
                  def self.error_message(schema)
         
     | 
| 
      
 142 
     | 
    
         
            +
                    exclusivity = exclusive?(schema) ? 'exclusively' : 'inclusively'
         
     | 
| 
      
 143 
     | 
    
         
            +
                    format("did not have a %s value of %s, %s", limit_name, limit(schema), exclusivity)
         
     | 
| 
      
 144 
     | 
    
         
            +
                  end
         
     | 
| 
      
 145 
     | 
    
         
            +
                end
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
                class MaximumAttribute < NumericLimitAttribute
         
     | 
| 
      
 148 
     | 
    
         
            +
                  def self.limit_name
         
     | 
| 
      
 149 
     | 
    
         
            +
                    'maximum'
         
     | 
| 
      
 150 
     | 
    
         
            +
                  end
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
                  def self.exclusive?(schema)
         
     | 
| 
      
 153 
     | 
    
         
            +
                    schema['exclusiveMaximum']
         
     | 
| 
      
 154 
     | 
    
         
            +
                  end
         
     | 
| 
      
 155 
     | 
    
         
            +
                end
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
                class MaximumInclusiveAttribute < MaximumAttribute
         
     | 
| 
      
 158 
     | 
    
         
            +
                  def self.exclusive?(schema)
         
     | 
| 
      
 159 
     | 
    
         
            +
                    schema['maximumCanEqual'] == false
         
     | 
| 
      
 160 
     | 
    
         
            +
                  end
         
     | 
| 
      
 161 
     | 
    
         
            +
                end
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
                class MinimumAttribute < NumericLimitAttribute
         
     | 
| 
      
 164 
     | 
    
         
            +
                  def self.limit_name
         
     | 
| 
      
 165 
     | 
    
         
            +
                    'minimum'
         
     | 
| 
      
 166 
     | 
    
         
            +
                  end
         
     | 
| 
      
 167 
     | 
    
         
            +
             
     | 
| 
      
 168 
     | 
    
         
            +
                  def self.exclusive?(schema)
         
     | 
| 
      
 169 
     | 
    
         
            +
                    schema['exclusiveMinimum']
         
     | 
| 
      
 170 
     | 
    
         
            +
                  end
         
     | 
| 
      
 171 
     | 
    
         
            +
                end
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
                class MinimumInclusiveAttribute < MinimumAttribute
         
     | 
| 
      
 174 
     | 
    
         
            +
                  def self.exclusive?(schema)
         
     | 
| 
      
 175 
     | 
    
         
            +
                    schema['minimumCanEqual'] == false
         
     | 
| 
      
 176 
     | 
    
         
            +
                  end
         
     | 
| 
      
 177 
     | 
    
         
            +
                end
         
     | 
| 
      
 178 
     | 
    
         
            +
              end
         
     | 
| 
      
 179 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -4,12 +4,13 @@ module JSON 
     | 
|
| 
       4 
4 
     | 
    
         
             
              class Schema
         
     | 
| 
       5 
5 
     | 
    
         
             
                class MaxDecimalAttribute < Attribute
         
     | 
| 
       6 
6 
     | 
    
         
             
                  def self.validate(current_schema, data, fragments, processor, validator, options = {})
         
     | 
| 
       7 
     | 
    
         
            -
                     
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
                       
     | 
| 
      
 7 
     | 
    
         
            +
                    return unless data.is_a?(Numeric)
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                    max_decimal_places = current_schema.schema['maxDecimal']
         
     | 
| 
      
 10 
     | 
    
         
            +
                    s = data.to_s.split(".")[1]
         
     | 
| 
      
 11 
     | 
    
         
            +
                    if s && s.length > max_decimal_places
         
     | 
| 
      
 12 
     | 
    
         
            +
                      message = "The property '#{build_fragment(fragments)}' had more decimal places than the allowed #{max_decimal_places}"
         
     | 
| 
      
 13 
     | 
    
         
            +
                      validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
         
     | 
| 
       13 
14 
     | 
    
         
             
                    end
         
     | 
| 
       14 
15 
     | 
    
         
             
                  end
         
     | 
| 
       15 
16 
     | 
    
         
             
                end
         
     | 
| 
         @@ -1,17 +1,10 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'json-schema/ 
     | 
| 
      
 1 
     | 
    
         
            +
            require 'json-schema/attributes/divisibleby'
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            module JSON
         
     | 
| 
       4 
4 
     | 
    
         
             
              class Schema
         
     | 
| 
       5 
     | 
    
         
            -
                class MultipleOfAttribute <  
     | 
| 
       6 
     | 
    
         
            -
                  def self. 
     | 
| 
       7 
     | 
    
         
            -
                     
     | 
| 
       8 
     | 
    
         
            -
                      if current_schema.schema['multipleOf'] == 0 ||
         
     | 
| 
       9 
     | 
    
         
            -
                         current_schema.schema['multipleOf'] == 0.0 ||
         
     | 
| 
       10 
     | 
    
         
            -
                         (BigDecimal.new(data.to_s) % BigDecimal.new(current_schema.schema['multipleOf'].to_s)).to_f != 0
         
     | 
| 
       11 
     | 
    
         
            -
                         message = "The property '#{build_fragment(fragments)}' was not divisible by #{current_schema.schema['multipleOf']}"
         
     | 
| 
       12 
     | 
    
         
            -
                         validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
         
     | 
| 
       13 
     | 
    
         
            -
                      end
         
     | 
| 
       14 
     | 
    
         
            -
                    end
         
     | 
| 
      
 5 
     | 
    
         
            +
                class MultipleOfAttribute < DivisibleByAttribute
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def self.keyword
         
     | 
| 
      
 7 
     | 
    
         
            +
                    'multipleOf'
         
     | 
| 
       15 
8 
     | 
    
         
             
                  end
         
     | 
| 
       16 
9 
     | 
    
         
             
                end
         
     | 
| 
       17 
10 
     | 
    
         
             
              end
         
     | 
| 
         @@ -4,10 +4,10 @@ module JSON 
     | 
|
| 
       4 
4 
     | 
    
         
             
              class Schema
         
     | 
| 
       5 
5 
     | 
    
         
             
                class NotAttribute < Attribute
         
     | 
| 
       6 
6 
     | 
    
         
             
                  def self.validate(current_schema, data, fragments, processor, validator, options = {})
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
7 
     | 
    
         
             
                    schema = JSON::Schema.new(current_schema.schema['not'],current_schema.uri,validator)
         
     | 
| 
       9 
8 
     | 
    
         
             
                    failed = true
         
     | 
| 
       10 
9 
     | 
    
         
             
                    errors_copy = processor.validation_errors.clone
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
       11 
11 
     | 
    
         
             
                    begin
         
     | 
| 
       12 
12 
     | 
    
         
             
                      schema.validate(data,fragments,processor,options)
         
     | 
| 
       13 
13 
     | 
    
         
             
                      # If we're recording errors, we don't throw an exception. Instead, check the errors array length
         
     | 
| 
         @@ -5,25 +5,34 @@ module JSON 
     | 
|
| 
       5 
5 
     | 
    
         
             
                class OneOfAttribute < Attribute
         
     | 
| 
       6 
6 
     | 
    
         
             
                  def self.validate(current_schema, data, fragments, processor, validator, options = {})
         
     | 
| 
       7 
7 
     | 
    
         
             
                    validation_errors = 0
         
     | 
| 
       8 
     | 
    
         
            -
                    current_schema.schema['oneOf'] 
     | 
| 
      
 8 
     | 
    
         
            +
                    one_of = current_schema.schema['oneOf']
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                    original_data = data.is_a?(Hash) ? data.clone : data
         
     | 
| 
      
 11 
     | 
    
         
            +
                    success_data = nil
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                    one_of.each do |element|
         
     | 
| 
       9 
14 
     | 
    
         
             
                      schema = JSON::Schema.new(element,current_schema.uri,validator)
         
     | 
| 
       10 
15 
     | 
    
         | 
| 
       11 
16 
     | 
    
         
             
                      begin
         
     | 
| 
       12 
17 
     | 
    
         
             
                        # need to raise exceptions on error because
         
     | 
| 
       13 
18 
     | 
    
         
             
                        # schema.validate doesn't reliably return true/false
         
     | 
| 
       14 
19 
     | 
    
         
             
                        schema.validate(data,fragments,processor,options.merge(:record_errors => false))
         
     | 
| 
      
 20 
     | 
    
         
            +
                        success_data = data.is_a?(Hash) ? data.clone : data
         
     | 
| 
       15 
21 
     | 
    
         
             
                      rescue ValidationError
         
     | 
| 
       16 
22 
     | 
    
         
             
                        validation_errors += 1
         
     | 
| 
       17 
23 
     | 
    
         
             
                      end
         
     | 
| 
       18 
24 
     | 
    
         | 
| 
      
 25 
     | 
    
         
            +
                      data = original_data
         
     | 
| 
      
 26 
     | 
    
         
            +
                    end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                    if validation_errors == one_of.length - 1
         
     | 
| 
      
 29 
     | 
    
         
            +
                      data = success_data
         
     | 
| 
      
 30 
     | 
    
         
            +
                      return
         
     | 
| 
       19 
31 
     | 
    
         
             
                    end
         
     | 
| 
       20 
32 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
                     
     | 
| 
       22 
     | 
    
         
            -
                    when current_schema.schema['oneOf'].length - 1 # correct, matched only one
         
     | 
| 
       23 
     | 
    
         
            -
                      message = nil
         
     | 
| 
       24 
     | 
    
         
            -
                    when current_schema.schema['oneOf'].length  # didn't match any
         
     | 
| 
      
 33 
     | 
    
         
            +
                    if validation_errors == one_of.length
         
     | 
| 
       25 
34 
     | 
    
         
             
                      message = "The property '#{build_fragment(fragments)}' of type #{data.class} did not match any of the required schemas"
         
     | 
| 
       26 
     | 
    
         
            -
                    else 
     | 
| 
      
 35 
     | 
    
         
            +
                    else
         
     | 
| 
       27 
36 
     | 
    
         
             
                      message = "The property '#{build_fragment(fragments)}' of type #{data.class} matched more than one of the required schemas"
         
     | 
| 
       28 
37 
     | 
    
         
             
                    end
         
     | 
| 
       29 
38 
     | 
    
         | 
| 
         @@ -4,12 +4,13 @@ module JSON 
     | 
|
| 
       4 
4 
     | 
    
         
             
              class Schema
         
     | 
| 
       5 
5 
     | 
    
         
             
                class PatternAttribute < Attribute
         
     | 
| 
       6 
6 
     | 
    
         
             
                  def self.validate(current_schema, data, fragments, processor, validator, options = {})
         
     | 
| 
       7 
     | 
    
         
            -
                     
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
                       
     | 
| 
      
 7 
     | 
    
         
            +
                    return unless data.is_a?(String)
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                    pattern = current_schema.schema['pattern']
         
     | 
| 
      
 10 
     | 
    
         
            +
                    regexp  = Regexp.new(pattern)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    unless regexp.match(data)
         
     | 
| 
      
 12 
     | 
    
         
            +
                      message = "The property '#{build_fragment(fragments)}' value #{data.inspect} did not match the regex '#{pattern}'"
         
     | 
| 
      
 13 
     | 
    
         
            +
                      validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
         
     | 
| 
       13 
14 
     | 
    
         
             
                    end
         
     | 
| 
       14 
15 
     | 
    
         
             
                  end
         
     | 
| 
       15 
16 
     | 
    
         
             
                end
         
     | 
| 
         @@ -4,19 +4,16 @@ module JSON 
     | 
|
| 
       4 
4 
     | 
    
         
             
              class Schema
         
     | 
| 
       5 
5 
     | 
    
         
             
                class PatternPropertiesAttribute < Attribute
         
     | 
| 
       6 
6 
     | 
    
         
             
                  def self.validate(current_schema, data, fragments, processor, validator, options = {})
         
     | 
| 
       7 
     | 
    
         
            -
                     
     | 
| 
       8 
     | 
    
         
            -
                      current_schema.schema['patternProperties'].each do |property,property_schema|
         
     | 
| 
       9 
     | 
    
         
            -
                        r = Regexp.new(property)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    return unless data.is_a?(Hash)
         
     | 
| 
       10 
8 
     | 
    
         | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
                        end
         
     | 
| 
      
 9 
     | 
    
         
            +
                    current_schema.schema['patternProperties'].each do |property, property_schema|
         
     | 
| 
      
 10 
     | 
    
         
            +
                      regexp = Regexp.new(property)
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                      # Check each key in the data hash to see if it matches the regex
         
     | 
| 
      
 13 
     | 
    
         
            +
                      data.each do |key, value|
         
     | 
| 
      
 14 
     | 
    
         
            +
                        next unless regexp.match(key)
         
     | 
| 
      
 15 
     | 
    
         
            +
                        schema = JSON::Schema.new(property_schema, current_schema.uri, validator)
         
     | 
| 
      
 16 
     | 
    
         
            +
                        schema.validate(data[key], fragments + [key], processor, options)
         
     | 
| 
       20 
17 
     | 
    
         
             
                      end
         
     | 
| 
       21 
18 
     | 
    
         
             
                    end
         
     | 
| 
       22 
19 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -3,55 +3,71 @@ require 'json-schema/attribute' 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module JSON
         
     | 
| 
       4 
4 
     | 
    
         
             
              class Schema
         
     | 
| 
       5 
5 
     | 
    
         
             
                class PropertiesAttribute < Attribute
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def self.required?(schema, options)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    schema.fetch('required') { options[:strict] }
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
       6 
10 
     | 
    
         
             
                  def self.validate(current_schema, data, fragments, processor, validator, options = {})
         
     | 
| 
       7 
     | 
    
         
            -
                     
     | 
| 
       8 
     | 
    
         
            -
                      current_schema.schema['properties'].each do |property,property_schema|
         
     | 
| 
       9 
     | 
    
         
            -
                        if !data.has_key?(property.to_s) &&
         
     | 
| 
       10 
     | 
    
         
            -
                           property_schema['default'] &&
         
     | 
| 
       11 
     | 
    
         
            -
                           !property_schema['readonly'] &&
         
     | 
| 
       12 
     | 
    
         
            -
                           options[:insert_defaults]
         
     | 
| 
       13 
     | 
    
         
            -
                          default = property_schema['default']
         
     | 
| 
       14 
     | 
    
         
            -
                          data[property.to_s] = (default.is_a?(Hash) ? default.clone : default)
         
     | 
| 
       15 
     | 
    
         
            -
                        end
         
     | 
| 
      
 11 
     | 
    
         
            +
                    return unless data.is_a?(Hash)
         
     | 
| 
       16 
12 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                        end
         
     | 
| 
      
 13 
     | 
    
         
            +
                    schema = current_schema.schema
         
     | 
| 
      
 14 
     | 
    
         
            +
                    schema['properties'].each do |property, property_schema|
         
     | 
| 
      
 15 
     | 
    
         
            +
                      property = property.to_s
         
     | 
| 
       21 
16 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
                           
     | 
| 
       24 
     | 
    
         
            -
                           
     | 
| 
       25 
     | 
    
         
            -
                           
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
                         
     | 
| 
      
 17 
     | 
    
         
            +
                      if !data.key?(property) &&
         
     | 
| 
      
 18 
     | 
    
         
            +
                          options[:insert_defaults] &&
         
     | 
| 
      
 19 
     | 
    
         
            +
                          property_schema['default'] &&
         
     | 
| 
      
 20 
     | 
    
         
            +
                          !property_schema['readonly']
         
     | 
| 
      
 21 
     | 
    
         
            +
                        default = property_schema['default']
         
     | 
| 
      
 22 
     | 
    
         
            +
                        data[property] = default.is_a?(Hash) ? default.clone : default
         
     | 
| 
      
 23 
     | 
    
         
            +
                      end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                      if required?(property_schema, options) && !data.has_key?(property)
         
     | 
| 
      
 26 
     | 
    
         
            +
                        message = "The property '#{build_fragment(fragments)}' did not contain a required property of '#{property}'"
         
     | 
| 
      
 27 
     | 
    
         
            +
                        validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
         
     | 
| 
      
 28 
     | 
    
         
            +
                      end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                      if data.has_key?(property)
         
     | 
| 
      
 31 
     | 
    
         
            +
                        expected_schema = JSON::Schema.new(property_schema, current_schema.uri, validator)
         
     | 
| 
      
 32 
     | 
    
         
            +
                        expected_schema.validate(data[property], fragments + [property], processor, options)
         
     | 
| 
       28 
33 
     | 
    
         
             
                      end
         
     | 
| 
      
 34 
     | 
    
         
            +
                    end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                    # When strict is true, ensure no undefined properties exist in the data
         
     | 
| 
      
 37 
     | 
    
         
            +
                    return unless options[:strict] == true && !schema.key?('additionalProperties')
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                    diff = data.select do |k, v|
         
     | 
| 
      
 40 
     | 
    
         
            +
                      k = k.to_s
         
     | 
| 
       29 
41 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
                       
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
                         
     | 
| 
       33 
     | 
    
         
            -
                           
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
                             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
                              if r.match(k)
         
     | 
| 
       38 
     | 
    
         
            -
                                match = true
         
     | 
| 
       39 
     | 
    
         
            -
                                break
         
     | 
| 
       40 
     | 
    
         
            -
                              end
         
     | 
| 
       41 
     | 
    
         
            -
                            end
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
                            !current_schema.schema['properties'].has_key?(k.to_s) && !match
         
     | 
| 
       44 
     | 
    
         
            -
                          else
         
     | 
| 
       45 
     | 
    
         
            -
                            !current_schema.schema['properties'].has_key?(k.to_s)
         
     | 
| 
      
 42 
     | 
    
         
            +
                      if schema.has_key?('patternProperties')
         
     | 
| 
      
 43 
     | 
    
         
            +
                        match = false
         
     | 
| 
      
 44 
     | 
    
         
            +
                        schema['patternProperties'].each do |property, property_schema|
         
     | 
| 
      
 45 
     | 
    
         
            +
                          regexp = Regexp.new(property)
         
     | 
| 
      
 46 
     | 
    
         
            +
                          if regexp.match(k)
         
     | 
| 
      
 47 
     | 
    
         
            +
                            match = true
         
     | 
| 
      
 48 
     | 
    
         
            +
                            break
         
     | 
| 
       46 
49 
     | 
    
         
             
                          end
         
     | 
| 
       47 
50 
     | 
    
         
             
                        end
         
     | 
| 
       48 
51 
     | 
    
         | 
| 
       49 
     | 
    
         
            -
                         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
                        end
         
     | 
| 
      
 52 
     | 
    
         
            +
                        !schema['properties'].has_key?(k) && !match
         
     | 
| 
      
 53 
     | 
    
         
            +
                      else
         
     | 
| 
      
 54 
     | 
    
         
            +
                        !schema['properties'].has_key?(k)
         
     | 
| 
       53 
55 
     | 
    
         
             
                      end
         
     | 
| 
       54 
56 
     | 
    
         
             
                    end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                    if diff.size > 0
         
     | 
| 
      
 59 
     | 
    
         
            +
                      properties = data.to_a.map { |(key, _)| key }.join(', ')
         
     | 
| 
      
 60 
     | 
    
         
            +
                      message = "The property '#{build_fragment(fragments)}' contained undefined properties: '#{properties}"
         
     | 
| 
      
 61 
     | 
    
         
            +
                      validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
         
     | 
| 
      
 62 
     | 
    
         
            +
                    end
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
                end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                class PropertiesV4Attribute < PropertiesAttribute
         
     | 
| 
      
 67 
     | 
    
         
            +
                  # draft4 relies on its own RequiredAttribute validation at a higher level, rather than
         
     | 
| 
      
 68 
     | 
    
         
            +
                  # as an attribute of individual properties.
         
     | 
| 
      
 69 
     | 
    
         
            +
                  def self.required?(schema, options)
         
     | 
| 
      
 70 
     | 
    
         
            +
                    options[:strict] == true
         
     | 
| 
       55 
71 
     | 
    
         
             
                  end
         
     | 
| 
       56 
72 
     | 
    
         
             
                end
         
     | 
| 
       57 
73 
     | 
    
         
             
              end
         
     |