json-schema-pvdgm 2.3.1

Sign up to get free protection for your applications and to get access to all the features.
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