json-schema-pvdgm 2.3.1

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.
Files changed (96) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +19 -0
  3. data/README.textile +354 -0
  4. data/lib/json-schema.rb +25 -0
  5. data/lib/json-schema/attributes/additionalitems.rb +23 -0
  6. data/lib/json-schema/attributes/additionalproperties.rb +67 -0
  7. data/lib/json-schema/attributes/allof.rb +37 -0
  8. data/lib/json-schema/attributes/anyof.rb +41 -0
  9. data/lib/json-schema/attributes/dependencies.rb +30 -0
  10. data/lib/json-schema/attributes/dependencies_v4.rb +20 -0
  11. data/lib/json-schema/attributes/disallow.rb +11 -0
  12. data/lib/json-schema/attributes/divisibleby.rb +16 -0
  13. data/lib/json-schema/attributes/enum.rb +24 -0
  14. data/lib/json-schema/attributes/extends.rb +49 -0
  15. data/lib/json-schema/attributes/format.rb +123 -0
  16. data/lib/json-schema/attributes/items.rb +25 -0
  17. data/lib/json-schema/attributes/maxdecimal.rb +15 -0
  18. data/lib/json-schema/attributes/maximum.rb +15 -0
  19. data/lib/json-schema/attributes/maximum_inclusive.rb +15 -0
  20. data/lib/json-schema/attributes/maxitems.rb +12 -0
  21. data/lib/json-schema/attributes/maxlength.rb +14 -0
  22. data/lib/json-schema/attributes/maxproperties.rb +12 -0
  23. data/lib/json-schema/attributes/minimum.rb +15 -0
  24. data/lib/json-schema/attributes/minimum_inclusive.rb +15 -0
  25. data/lib/json-schema/attributes/minitems.rb +12 -0
  26. data/lib/json-schema/attributes/minlength.rb +14 -0
  27. data/lib/json-schema/attributes/minproperties.rb +12 -0
  28. data/lib/json-schema/attributes/multipleof.rb +16 -0
  29. data/lib/json-schema/attributes/not.rb +28 -0
  30. data/lib/json-schema/attributes/oneof.rb +32 -0
  31. data/lib/json-schema/attributes/pattern.rb +15 -0
  32. data/lib/json-schema/attributes/patternproperties.rb +23 -0
  33. data/lib/json-schema/attributes/properties.rb +58 -0
  34. data/lib/json-schema/attributes/properties_optional.rb +23 -0
  35. data/lib/json-schema/attributes/properties_v4.rb +57 -0
  36. data/lib/json-schema/attributes/ref.rb +70 -0
  37. data/lib/json-schema/attributes/required.rb +23 -0
  38. data/lib/json-schema/attributes/type.rb +102 -0
  39. data/lib/json-schema/attributes/type_v4.rb +54 -0
  40. data/lib/json-schema/attributes/uniqueitems.rb +16 -0
  41. data/lib/json-schema/model_validator.rb +85 -0
  42. data/lib/json-schema/schema.rb +73 -0
  43. data/lib/json-schema/uri/file.rb +36 -0
  44. data/lib/json-schema/uri/uuid.rb +285 -0
  45. data/lib/json-schema/util/array_set.rb +14 -0
  46. data/lib/json-schema/util/hash.rb +8 -0
  47. data/lib/json-schema/validator.rb +672 -0
  48. data/lib/json-schema/validators/draft1.rb +32 -0
  49. data/lib/json-schema/validators/draft2.rb +33 -0
  50. data/lib/json-schema/validators/draft3.rb +38 -0
  51. data/lib/json-schema/validators/draft4.rb +45 -0
  52. data/resources/draft-01.json +155 -0
  53. data/resources/draft-02.json +166 -0
  54. data/resources/draft-03.json +174 -0
  55. data/resources/draft-04.json +150 -0
  56. data/test/data/all_of_ref_data.json +3 -0
  57. data/test/data/any_of_ref_data.json +7 -0
  58. data/test/data/bad_data_1.json +3 -0
  59. data/test/data/good_data_1.json +3 -0
  60. data/test/data/one_of_ref_links_data.json +5 -0
  61. data/test/schemas/all_of_ref_base_schema.json +6 -0
  62. data/test/schemas/all_of_ref_schema.json +7 -0
  63. data/test/schemas/any_of_ref_jane_schema.json +4 -0
  64. data/test/schemas/any_of_ref_jimmy_schema.json +4 -0
  65. data/test/schemas/any_of_ref_john_schema.json +4 -0
  66. data/test/schemas/any_of_ref_schema.json +15 -0
  67. data/test/schemas/extends_and_additionalProperties-1-filename.schema.json +34 -0
  68. data/test/schemas/extends_and_additionalProperties-1-ref.schema.json +34 -0
  69. data/test/schemas/extends_and_additionalProperties-2-filename.schema.json +33 -0
  70. data/test/schemas/extends_and_additionalProperties-2-ref.schema.json +33 -0
  71. data/test/schemas/good_schema_1.json +10 -0
  72. data/test/schemas/good_schema_2.json +10 -0
  73. data/test/schemas/good_schema_extends1.json +10 -0
  74. data/test/schemas/good_schema_extends2.json +13 -0
  75. data/test/schemas/inner.schema.json +21 -0
  76. data/test/schemas/one_of_ref_links_schema.json +16 -0
  77. data/test/schemas/self_link_schema.json +17 -0
  78. data/test/schemas/up_link_schema.json +17 -0
  79. data/test/test_all_of_ref_schema.rb +11 -0
  80. data/test/test_any_of_ref_schema.rb +11 -0
  81. data/test/test_bad_schema_ref.rb +33 -0
  82. data/test/test_extended_schema.rb +68 -0
  83. data/test/test_extends_and_additionalProperties.rb +50 -0
  84. data/test/test_files_v3.rb +52 -0
  85. data/test/test_fragment_resolution.rb +31 -0
  86. data/test/test_full_validation.rb +209 -0
  87. data/test/test_jsonschema_draft1.rb +701 -0
  88. data/test/test_jsonschema_draft2.rb +773 -0
  89. data/test/test_jsonschema_draft3.rb +1236 -0
  90. data/test/test_jsonschema_draft4.rb +1356 -0
  91. data/test/test_model_validator.rb +52 -0
  92. data/test/test_one_of.rb +42 -0
  93. data/test/test_ruby_schema.rb +38 -0
  94. data/test/test_schema_type_attribute.rb +21 -0
  95. data/test/test_schema_validation.rb +85 -0
  96. metadata +180 -0
@@ -0,0 +1,14 @@
1
+ module JSON
2
+ class Schema
3
+ class MaxLengthAttribute < Attribute
4
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
5
+ if data.is_a?(String)
6
+ if data.length > current_schema.schema['maxLength']
7
+ message = "The property '#{build_fragment(fragments)}' was not of a maximum string length of #{current_schema.schema['maxLength']}"
8
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :max_length })
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ module JSON
2
+ class Schema
3
+ class MaxPropertiesAttribute < Attribute
4
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
5
+ if data.is_a?(Hash) && (data.size > current_schema.schema['maxProperties'])
6
+ message = "The property '#{build_fragment(fragments)}' did not contain a minimum number of properties #{current_schema.schema['maxProperties']}"
7
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :max_properties })
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ module JSON
2
+ class Schema
3
+ class MinimumAttribute < Attribute
4
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
5
+ if data.is_a?(Numeric)
6
+ if (current_schema.schema['exclusiveMinimum'] ? data <= current_schema.schema['minimum'] : data < current_schema.schema['minimum'])
7
+ message = "The property '#{build_fragment(fragments)}' did not have a minimum value of #{current_schema.schema['minimum']}, "
8
+ message += current_schema.schema['exclusiveMinimum'] ? 'exclusively' : 'inclusively'
9
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :minimum })
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module JSON
2
+ class Schema
3
+ class MinimumInclusiveAttribute < Attribute
4
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
5
+ if data.is_a?(Numeric)
6
+ if (current_schema.schema['minimumCanEqual'] == false ? data <= current_schema.schema['minimum'] : data < current_schema.schema['minimum'])
7
+ message = "The property '#{build_fragment(fragments)}' did not have a minimum value of #{current_schema.schema['minimum']}, "
8
+ message += current_schema.schema['exclusiveMinimum'] ? 'exclusively' : 'inclusively'
9
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :minimum_inclusive })
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ module JSON
2
+ class Schema
3
+ class MinItemsAttribute < Attribute
4
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
5
+ if data.is_a?(Array) && (data.compact.size < current_schema.schema['minItems'])
6
+ message = "The property '#{build_fragment(fragments)}' did not contain a minimum number of items #{current_schema.schema['minItems']}"
7
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :min_items })
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ module JSON
2
+ class Schema
3
+ class MinLengthAttribute < Attribute
4
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
5
+ if data.is_a?(String)
6
+ if data.length < current_schema.schema['minLength']
7
+ message = "The property '#{build_fragment(fragments)}' was not of a minimum string length of #{current_schema.schema['minLength']}"
8
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :min_length })
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ module JSON
2
+ class Schema
3
+ class MinPropertiesAttribute < Attribute
4
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
5
+ if data.is_a?(Hash) && (data.size < current_schema.schema['minProperties'])
6
+ message = "The property '#{build_fragment(fragments)}' did not contain a minimum number of properties #{current_schema.schema['minProperties']}"
7
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :min_properties })
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ module JSON
2
+ class Schema
3
+ class MultipleOfAttribute < Attribute
4
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
5
+ if data.is_a?(Numeric)
6
+ if current_schema.schema['multipleOf'] == 0 ||
7
+ current_schema.schema['multipleOf'] == 0.0 ||
8
+ (BigDecimal.new(data.to_s) % BigDecimal.new(current_schema.schema['multipleOf'].to_s)).to_f != 0
9
+ message = "The property '#{build_fragment(fragments)}' was not divisible by #{current_schema.schema['multipleOf']}"
10
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :multiple_of })
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,28 @@
1
+ module JSON
2
+ class Schema
3
+ class NotAttribute < Attribute
4
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
5
+
6
+ schema = JSON::Schema.new(current_schema.schema['not'],current_schema.uri,validator)
7
+ failed = true
8
+ errors_copy = processor.validation_errors.clone
9
+ begin
10
+ schema.validate(data,fragments,processor,options)
11
+ # If we're recording errors, we don't throw an exception. Instead, check the errors array length
12
+ if options[:record_errors] && errors_copy.length != processor.validation_errors.length
13
+ processor.validation_errors.replace(errors_copy)
14
+ else
15
+ message = "The property '#{build_fragment(fragments)}' of type #{data.class} matched the disallowed schema"
16
+ failed = false
17
+ end
18
+ rescue
19
+ # Yay, we failed validation.
20
+ end
21
+
22
+ unless failed
23
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :not })
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,32 @@
1
+ module JSON
2
+ class Schema
3
+ class OneOfAttribute < Attribute
4
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
5
+ validation_errors = 0
6
+ current_schema.schema['oneOf'].each do |element|
7
+ schema = JSON::Schema.new(element,current_schema.uri,validator)
8
+
9
+ begin
10
+ # need to raise exceptions on error because
11
+ # schema.validate doesn't reliably return true/false
12
+ schema.validate(data,fragments,processor,options.merge(:record_errors => false))
13
+ rescue ValidationError
14
+ validation_errors += 1
15
+ end
16
+
17
+ end
18
+
19
+ case validation_errors
20
+ when current_schema.schema['oneOf'].length - 1 # correct, matched only one
21
+ message = nil
22
+ when current_schema.schema['oneOf'].length # didn't match any
23
+ message = "The property '#{build_fragment(fragments)}' of type #{data.class} did not match any of the required schemas"
24
+ else # too many matches
25
+ message = "The property '#{build_fragment(fragments)}' of type #{data.class} matched more than one of the required schemas"
26
+ end
27
+
28
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :one_of }) if message
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,15 @@
1
+ module JSON
2
+ class Schema
3
+ class PatternAttribute < Attribute
4
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
5
+ if data.is_a?(String)
6
+ r = Regexp.new(current_schema.schema['pattern'])
7
+ if (r.match(data)).nil?
8
+ message = "The property '#{build_fragment(fragments)}' value #{data.inspect} did not match the regex '#{current_schema.schema['pattern']}'"
9
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :pattern })
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ module JSON
2
+ class Schema
3
+ class PatternPropertiesAttribute < Attribute
4
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
5
+ if data.is_a?(Hash)
6
+ current_schema.schema['patternProperties'].each do |property,property_schema|
7
+ r = Regexp.new(property)
8
+
9
+ # Check each key in the data hash to see if it matches the regex
10
+ data.each do |key,value|
11
+ if r.match(key)
12
+ schema = JSON::Schema.new(property_schema,current_schema.uri,validator)
13
+ fragments << key
14
+ schema.validate(data[key],fragments,processor,options)
15
+ fragments.pop
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,58 @@
1
+ module JSON
2
+ class Schema
3
+ class PropertiesAttribute < Attribute
4
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
5
+ if data.is_a?(Hash)
6
+ current_schema.schema['properties'].each do |property,property_schema|
7
+ if !data.has_key?(property.to_s) &&
8
+ !data.has_key?(property.to_sym) &&
9
+ property_schema['default'] &&
10
+ !property_schema['readonly'] &&
11
+ options[:insert_defaults]
12
+ default = property_schema['default']
13
+ data[property.to_s] = (default.is_a?(Hash) ? default.clone : default)
14
+ end
15
+
16
+
17
+ if (property_schema['required'] || options[:strict] == true) && !data.has_key?(property.to_s) && !data.has_key?(property.to_sym)
18
+ message = "The property '#{build_fragment(fragments)}' did not contain a required property of '#{property}'"
19
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: property.to_sym, failure: :properties })
20
+ end
21
+
22
+ if data.has_key?(property.to_s) || data.has_key?(property.to_sym)
23
+ schema = JSON::Schema.new(property_schema,current_schema.uri,validator)
24
+ fragments << property.to_s
25
+ schema.validate(data[property.to_s],fragments,processor,options)
26
+ fragments.pop
27
+ end
28
+ end
29
+
30
+ # When strict is true, ensure no undefined properties exist in the data
31
+ if (options[:strict] == true && !current_schema.schema.has_key?('additionalProperties'))
32
+ diff = data.select do |k,v|
33
+ if current_schema.schema.has_key?('patternProperties')
34
+ match = false
35
+ current_schema.schema['patternProperties'].each do |property,property_schema|
36
+ r = Regexp.new(property)
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) && !current_schema.schema['properties'].has_key?(k.to_sym) && !match
44
+ else
45
+ !current_schema.schema['properties'].has_key?(k.to_s) && !current_schema.schema['properties'].has_key?(k.to_sym)
46
+ end
47
+ end
48
+
49
+ if diff.size > 0
50
+ message = "The property '#{build_fragment(fragments)}' contained undefined properties: '#{diff.keys.join(", ")}'"
51
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,23 @@
1
+ module JSON
2
+ class Schema
3
+ class PropertiesOptionalAttribute < Attribute
4
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
5
+ if data.is_a?(Hash)
6
+ current_schema.schema['properties'].each do |property,property_schema|
7
+ if ((property_schema['optional'].nil? || property_schema['optional'] == false) && !data.has_key?(property.to_s) && !data.has_key?(property.to_sym))
8
+ message = "The property '#{build_fragment(fragments)}' did not contain a required property of '#{property}'"
9
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: property.to_sym, failure: :properties_optional })
10
+ end
11
+
12
+ if data.has_key?(property.to_s) || data.has_key?(property.to_sym)
13
+ schema = JSON::Schema.new(property_schema,current_schema.uri,validator)
14
+ fragments << property
15
+ schema.validate(data[property],fragments,processor,options)
16
+ fragments.pop
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,57 @@
1
+ module JSON
2
+ class Schema
3
+ class PropertiesV4Attribute < Attribute
4
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
5
+ if data.is_a?(Hash)
6
+ current_schema.schema['properties'].each do |property,property_schema|
7
+ if !data.has_key?(property.to_s) &&
8
+ !data.has_key?(property.to_sym) &&
9
+ property_schema['default'] &&
10
+ !property_schema['readonly'] &&
11
+ options[:insert_defaults]
12
+ default = property_schema['default']
13
+ data[property.to_s] = (default.is_a?(Hash) ? default.clone : default)
14
+ end
15
+
16
+ if (options[:strict] == true && !data.has_key?(property.to_s) && !data.has_key?(property.to_sym))
17
+ message = "The property '#{build_fragment(fragments)}' did not contain a required property of '#{property}'"
18
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: property.to_sym, failure: :properties })
19
+ end
20
+
21
+ if data.has_key?(property.to_s) || data.has_key?(property.to_sym)
22
+ schema = JSON::Schema.new(property_schema,current_schema.uri,validator)
23
+ fragments << property.to_s
24
+ schema.validate(data[property.to_s],fragments,processor,options)
25
+ fragments.pop
26
+ end
27
+ end
28
+ end
29
+
30
+ # When strict is true, ensure no undefined properties exist in the data
31
+ if (options[:strict] == true && !current_schema.schema.has_key?('additionalProperties'))
32
+ diff = data.select do |k,v|
33
+ if current_schema.schema.has_key?('patternProperties')
34
+ match = false
35
+ current_schema.schema['patternProperties'].each do |property,property_schema|
36
+ r = Regexp.new(property)
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) && !current_schema.schema['properties'].has_key?(k.to_sym) && !match
44
+ else
45
+ !current_schema.schema['properties'].has_key?(k.to_s) && !current_schema.schema['properties'].has_key?(k.to_sym)
46
+ end
47
+ end
48
+
49
+ if diff.size > 0
50
+ message = "The property '#{build_fragment(fragments)}' contained undefined properties: '#{diff.keys.join(", ")}'"
51
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,70 @@
1
+ module JSON
2
+ class Schema
3
+ class RefAttribute < Attribute
4
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
5
+ uri,schema = get_referenced_uri_and_schema(current_schema.schema, current_schema, validator)
6
+
7
+ if schema
8
+ schema.validate(data, fragments, processor, options)
9
+ elsif uri
10
+ message = "The referenced schema '#{uri.to_s}' cannot be found"
11
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
12
+ else
13
+ message = "The property '#{build_fragment(fragments)}' was not a valid schema"
14
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
15
+ end
16
+ end
17
+
18
+ def self.get_referenced_uri_and_schema(s, current_schema, validator)
19
+ uri,schema = nil,nil
20
+
21
+ temp_uri = URI.parse(s['$ref'])
22
+ if temp_uri.relative?
23
+ temp_uri = current_schema.uri.clone
24
+ # Check for absolute path
25
+ path = s['$ref'].split("#")[0]
26
+ if path.nil? || path == ''
27
+ temp_uri.path = current_schema.uri.path
28
+ elsif path[0,1] == "/"
29
+ temp_uri.path = Pathname.new(path).cleanpath.to_s
30
+ else
31
+ temp_uri = current_schema.uri.merge(path)
32
+ end
33
+ temp_uri.fragment = s['$ref'].split("#")[1]
34
+ end
35
+ temp_uri.fragment = "" if temp_uri.fragment.nil?
36
+
37
+ # Grab the parent schema from the schema list
38
+ schema_key = temp_uri.to_s.split("#")[0] + "#"
39
+
40
+ ref_schema = JSON::Validator.schemas[schema_key]
41
+
42
+ if ref_schema
43
+ # Perform fragment resolution to retrieve the appropriate level for the schema
44
+ target_schema = ref_schema.schema
45
+ fragments = temp_uri.fragment.split("/")
46
+ fragment_path = ''
47
+ fragments.each do |fragment|
48
+ if fragment && fragment != ''
49
+ if target_schema.is_a?(Array)
50
+ target_schema = target_schema[fragment.to_i]
51
+ else
52
+ target_schema = target_schema[fragment]
53
+ end
54
+ fragment_path = fragment_path + "/#{fragment}"
55
+ if target_schema.nil?
56
+ raise SchemaError.new("The fragment '#{fragment_path}' does not exist on schema #{ref_schema.uri.to_s}")
57
+ end
58
+ end
59
+ end
60
+
61
+ # We have the schema finally, build it and validate!
62
+ uri = temp_uri
63
+ schema = JSON::Schema.new(target_schema,temp_uri,validator)
64
+ end
65
+
66
+ [uri,schema]
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,23 @@
1
+ module JSON
2
+ class Schema
3
+ class RequiredAttribute < Attribute
4
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
5
+ if data.is_a?(Hash)
6
+ current_schema.schema['required'].each do |property,property_schema|
7
+ if !data.has_key?(property.to_s) && !data.has_key?(property.to_sym)
8
+ prop_defaults = options[:insert_defaults] &&
9
+ current_schema.schema['properties'] &&
10
+ current_schema.schema['properties'][property] &&
11
+ !current_schema.schema['properties'][property]["default"].nil? &&
12
+ !current_schema.schema['properties'][property]["readonly"]
13
+ if !prop_defaults
14
+ message = "The property '#{build_fragment(fragments)}' did not contain a required property of '#{property}'"
15
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: property.to_sym, failure: :required })
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end