json-schema-ouidou 2.9.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.
Files changed (83) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +19 -0
  3. data/README.md +496 -0
  4. data/lib/json-schema/attribute.rb +57 -0
  5. data/lib/json-schema/attributes/additionalitems.rb +28 -0
  6. data/lib/json-schema/attributes/additionalproperties.rb +58 -0
  7. data/lib/json-schema/attributes/allof.rb +39 -0
  8. data/lib/json-schema/attributes/anyof.rb +47 -0
  9. data/lib/json-schema/attributes/dependencies.rb +38 -0
  10. data/lib/json-schema/attributes/dependencies_v4.rb +11 -0
  11. data/lib/json-schema/attributes/disallow.rb +12 -0
  12. data/lib/json-schema/attributes/divisibleby.rb +22 -0
  13. data/lib/json-schema/attributes/enum.rb +24 -0
  14. data/lib/json-schema/attributes/extends.rb +48 -0
  15. data/lib/json-schema/attributes/format.rb +14 -0
  16. data/lib/json-schema/attributes/formats/custom.rb +21 -0
  17. data/lib/json-schema/attributes/formats/date.rb +25 -0
  18. data/lib/json-schema/attributes/formats/date_time.rb +34 -0
  19. data/lib/json-schema/attributes/formats/date_time_v4.rb +15 -0
  20. data/lib/json-schema/attributes/formats/ip.rb +41 -0
  21. data/lib/json-schema/attributes/formats/time.rb +22 -0
  22. data/lib/json-schema/attributes/formats/uri.rb +18 -0
  23. data/lib/json-schema/attributes/items.rb +27 -0
  24. data/lib/json-schema/attributes/limit.rb +52 -0
  25. data/lib/json-schema/attributes/limits/items.rb +15 -0
  26. data/lib/json-schema/attributes/limits/length.rb +15 -0
  27. data/lib/json-schema/attributes/limits/max_items.rb +15 -0
  28. data/lib/json-schema/attributes/limits/max_length.rb +15 -0
  29. data/lib/json-schema/attributes/limits/max_properties.rb +15 -0
  30. data/lib/json-schema/attributes/limits/maximum.rb +15 -0
  31. data/lib/json-schema/attributes/limits/maximum_inclusive.rb +11 -0
  32. data/lib/json-schema/attributes/limits/min_items.rb +15 -0
  33. data/lib/json-schema/attributes/limits/min_length.rb +15 -0
  34. data/lib/json-schema/attributes/limits/min_properties.rb +15 -0
  35. data/lib/json-schema/attributes/limits/minimum.rb +15 -0
  36. data/lib/json-schema/attributes/limits/minimum_inclusive.rb +11 -0
  37. data/lib/json-schema/attributes/limits/numeric.rb +16 -0
  38. data/lib/json-schema/attributes/limits/properties.rb +15 -0
  39. data/lib/json-schema/attributes/maxdecimal.rb +18 -0
  40. data/lib/json-schema/attributes/multipleof.rb +11 -0
  41. data/lib/json-schema/attributes/not.rb +30 -0
  42. data/lib/json-schema/attributes/oneof.rb +56 -0
  43. data/lib/json-schema/attributes/pattern.rb +18 -0
  44. data/lib/json-schema/attributes/patternproperties.rb +22 -0
  45. data/lib/json-schema/attributes/properties.rb +66 -0
  46. data/lib/json-schema/attributes/properties_optional.rb +26 -0
  47. data/lib/json-schema/attributes/properties_v4.rb +13 -0
  48. data/lib/json-schema/attributes/ref.rb +61 -0
  49. data/lib/json-schema/attributes/required.rb +28 -0
  50. data/lib/json-schema/attributes/type.rb +73 -0
  51. data/lib/json-schema/attributes/type_v4.rb +29 -0
  52. data/lib/json-schema/attributes/uniqueitems.rb +20 -0
  53. data/lib/json-schema/errors/custom_format_error.rb +6 -0
  54. data/lib/json-schema/errors/json_load_error.rb +6 -0
  55. data/lib/json-schema/errors/json_parse_error.rb +6 -0
  56. data/lib/json-schema/errors/schema_error.rb +6 -0
  57. data/lib/json-schema/errors/schema_parse_error.rb +8 -0
  58. data/lib/json-schema/errors/uri_error.rb +6 -0
  59. data/lib/json-schema/errors/validation_error.rb +46 -0
  60. data/lib/json-schema/schema/reader.rb +140 -0
  61. data/lib/json-schema/schema/validator.rb +40 -0
  62. data/lib/json-schema/schema.rb +62 -0
  63. data/lib/json-schema/util/array_set.rb +20 -0
  64. data/lib/json-schema/util/uri.rb +110 -0
  65. data/lib/json-schema/util/uuid.rb +284 -0
  66. data/lib/json-schema/validator.rb +609 -0
  67. data/lib/json-schema/validators/draft1.rb +45 -0
  68. data/lib/json-schema/validators/draft2.rb +46 -0
  69. data/lib/json-schema/validators/draft3.rb +50 -0
  70. data/lib/json-schema/validators/draft4.rb +56 -0
  71. data/lib/json-schema/validators/draft6.rb +56 -0
  72. data/lib/json-schema/validators/hyper-draft1.rb +13 -0
  73. data/lib/json-schema/validators/hyper-draft2.rb +13 -0
  74. data/lib/json-schema/validators/hyper-draft3.rb +13 -0
  75. data/lib/json-schema/validators/hyper-draft4.rb +13 -0
  76. data/lib/json-schema/validators/hyper-draft6.rb +13 -0
  77. data/lib/json-schema.rb +18 -0
  78. data/resources/draft-01.json +155 -0
  79. data/resources/draft-02.json +166 -0
  80. data/resources/draft-03.json +174 -0
  81. data/resources/draft-04.json +150 -0
  82. data/resources/draft-06.json +150 -0
  83. metadata +197 -0
@@ -0,0 +1,15 @@
1
+ require 'json-schema/attributes/limits/length'
2
+
3
+ module JSON
4
+ class Schema
5
+ class MinLengthAttribute < LengthLimitAttribute
6
+ def self.limit_name
7
+ 'minLength'
8
+ end
9
+
10
+ def self.error_message(schema)
11
+ "was not of a minimum string length of #{limit(schema)}"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'json-schema/attributes/limits/properties'
2
+
3
+ module JSON
4
+ class Schema
5
+ class MinPropertiesAttribute < PropertiesLimitAttribute
6
+ def self.limit_name
7
+ 'minProperties'
8
+ end
9
+
10
+ def self.error_message(schema)
11
+ "did not contain a minimum number of properties #{limit(schema)}"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'json-schema/attributes/limits/numeric'
2
+
3
+ module JSON
4
+ class Schema
5
+ class MinimumAttribute < NumericLimitAttribute
6
+ def self.limit_name
7
+ 'minimum'
8
+ end
9
+
10
+ def self.exclusive?(schema)
11
+ schema['exclusiveMinimum']
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ require 'json-schema/attributes/limits/minimum'
2
+
3
+ module JSON
4
+ class Schema
5
+ class MinimumInclusiveAttribute < MinimumAttribute
6
+ def self.exclusive?(schema)
7
+ schema['minimumCanEqual'] == false
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ require 'json-schema/attributes/limit'
2
+
3
+ module JSON
4
+ class Schema
5
+ class NumericLimitAttribute < LimitAttribute
6
+ def self.acceptable_type
7
+ Numeric
8
+ end
9
+
10
+ def self.error_message(schema)
11
+ exclusivity = exclusive?(schema) ? 'exclusively' : 'inclusively'
12
+ format("did not have a %s value of %s, %s", limit_name, limit(schema), exclusivity)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ require 'json-schema/attributes/limit'
2
+
3
+ module JSON
4
+ class Schema
5
+ class PropertiesLimitAttribute < LimitAttribute
6
+ def self.acceptable_type
7
+ Hash
8
+ end
9
+
10
+ def self.value(data)
11
+ data.size
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ require 'json-schema/attribute'
2
+
3
+ module JSON
4
+ class Schema
5
+ class MaxDecimalAttribute < Attribute
6
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
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])
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ require 'json-schema/attributes/divisibleby'
2
+
3
+ module JSON
4
+ class Schema
5
+ class MultipleOfAttribute < DivisibleByAttribute
6
+ def self.keyword
7
+ 'multipleOf'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,30 @@
1
+ require 'json-schema/attribute'
2
+
3
+ module JSON
4
+ class Schema
5
+ class NotAttribute < Attribute
6
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
7
+ schema = JSON::Schema.new(current_schema.schema['not'],current_schema.uri,validator)
8
+ failed = true
9
+ errors_copy = processor.validation_errors.clone
10
+
11
+ begin
12
+ schema.validate(data,fragments,processor,options)
13
+ # If we're recording errors, we don't throw an exception. Instead, check the errors array length
14
+ if options[:record_errors] && errors_copy.length != processor.validation_errors.length
15
+ processor.validation_errors.replace(errors_copy)
16
+ else
17
+ message = "The property '#{build_fragment(fragments)}' of type #{type_of_data(data)} matched the disallowed schema"
18
+ failed = false
19
+ end
20
+ rescue ValidationError
21
+ # Yay, we failed validation.
22
+ end
23
+
24
+ unless failed
25
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,56 @@
1
+ require 'json-schema/attribute'
2
+
3
+ module JSON
4
+ class Schema
5
+ class OneOfAttribute < Attribute
6
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
7
+ errors = Hash.new { |hsh, k| hsh[k] = [] }
8
+
9
+ validation_error_count = 0
10
+ one_of = current_schema.schema['oneOf']
11
+
12
+ original_data = data.is_a?(Hash) ? data.clone : data
13
+ success_data = nil
14
+
15
+ valid = false
16
+
17
+ one_of.each_with_index do |element, schema_index|
18
+ schema = JSON::Schema.new(element,current_schema.uri,validator)
19
+ pre_validation_error_count = validation_errors(processor).count
20
+ begin
21
+ schema.validate(data,fragments,processor,options)
22
+ success_data = data.is_a?(Hash) ? data.clone : data
23
+ valid = true
24
+ rescue ValidationError
25
+ valid = false
26
+ end
27
+
28
+ diff = validation_errors(processor).count - pre_validation_error_count
29
+ valid = false if diff > 0
30
+ validation_error_count += 1 if !valid
31
+ while diff > 0
32
+ diff = diff - 1
33
+ errors["oneOf ##{schema_index}"].push(validation_errors(processor).pop)
34
+ end
35
+ data = original_data
36
+ end
37
+
38
+
39
+
40
+ if validation_error_count == one_of.length - 1
41
+ data = success_data
42
+ return
43
+ end
44
+
45
+ if validation_error_count == one_of.length
46
+ message = "The property '#{build_fragment(fragments)}' of type #{type_of_data(data)} did not match any of the required schemas"
47
+ else
48
+ message = "The property '#{build_fragment(fragments)}' of type #{type_of_data(data)} matched more than one of the required schemas"
49
+ end
50
+
51
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors]) if message
52
+ validation_errors(processor).last.sub_errors = errors if message
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,18 @@
1
+ require 'json-schema/attribute'
2
+
3
+ module JSON
4
+ class Schema
5
+ class PatternAttribute < Attribute
6
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
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])
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ require 'json-schema/attribute'
2
+
3
+ module JSON
4
+ class Schema
5
+ class PatternPropertiesAttribute < Attribute
6
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
7
+ return unless data.is_a?(Hash)
8
+
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)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,66 @@
1
+ require 'json-schema/attribute'
2
+
3
+ module JSON
4
+ class Schema
5
+ class PropertiesAttribute < Attribute
6
+ def self.required?(schema, options)
7
+ schema.fetch('required') { options[:strict] }
8
+ end
9
+
10
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
11
+ return unless data.is_a?(Hash)
12
+
13
+ schema = current_schema.schema
14
+ schema['properties'].each do |property, property_schema|
15
+ property = property.to_s
16
+
17
+ if !data.key?(property) &&
18
+ options[:insert_defaults] &&
19
+ property_schema.has_key?('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)
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
41
+
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
49
+ end
50
+ end
51
+
52
+ !schema['properties'].has_key?(k) && !match
53
+ else
54
+ !schema['properties'].has_key?(k)
55
+ end
56
+ end
57
+
58
+ if diff.size > 0
59
+ properties = diff.keys.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
+ end
66
+ end
@@ -0,0 +1,26 @@
1
+ require 'json-schema/attribute'
2
+
3
+ module JSON
4
+ class Schema
5
+ class PropertiesOptionalAttribute < Attribute
6
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
7
+ return unless data.is_a?(Hash)
8
+
9
+ schema = current_schema.schema
10
+ schema['properties'].each do |property, property_schema|
11
+ property = property.to_s
12
+
13
+ if !property_schema['optional'] && !data.key?(property)
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])
16
+ end
17
+
18
+ if data.has_key?(property)
19
+ expected_schema = JSON::Schema.new(property_schema, current_schema.uri, validator)
20
+ expected_schema.validate(data[property], fragments + [property], processor, options)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,13 @@
1
+ require 'json-schema/attributes/properties'
2
+
3
+ module JSON
4
+ class Schema
5
+ class PropertiesV4Attribute < PropertiesAttribute
6
+ # draft4 relies on its own RequiredAttribute validation at a higher level, rather than
7
+ # as an attribute of individual properties.
8
+ def self.required?(schema, options)
9
+ options[:strict] == true
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,61 @@
1
+ require 'json-schema/attribute'
2
+ require 'json-schema/errors/schema_error'
3
+ require 'json-schema/util/uri'
4
+
5
+ module JSON
6
+ class Schema
7
+ class RefAttribute < Attribute
8
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
9
+ uri,schema = get_referenced_uri_and_schema(current_schema.schema, current_schema, validator)
10
+
11
+ if schema
12
+ schema.validate(data, fragments, processor, options)
13
+ elsif uri
14
+ message = "The referenced schema '#{uri.to_s}' cannot be found"
15
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
16
+ else
17
+ message = "The property '#{build_fragment(fragments)}' was not a valid schema"
18
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
19
+ end
20
+ end
21
+
22
+ def self.get_referenced_uri_and_schema(s, current_schema, validator)
23
+ uri,schema = nil,nil
24
+
25
+ temp_uri = JSON::Util::URI.normalize_ref(s['$ref'], current_schema.uri)
26
+
27
+ # Grab the parent schema from the schema list
28
+ schema_key = temp_uri.to_s.split("#")[0] + "#"
29
+
30
+ ref_schema = JSON::Validator.schema_for_uri(schema_key)
31
+
32
+ if ref_schema
33
+ # Perform fragment resolution to retrieve the appropriate level for the schema
34
+ target_schema = ref_schema.schema
35
+ fragments = JSON::Util::URI.parse(JSON::Util::URI.unescape_uri(temp_uri)).fragment.split("/")
36
+ fragment_path = ''
37
+ fragments.each do |fragment|
38
+ if fragment && fragment != ''
39
+ fragment = fragment.gsub('~0', '~').gsub('~1', '/')
40
+ if target_schema.is_a?(Array)
41
+ target_schema = target_schema[fragment.to_i]
42
+ else
43
+ target_schema = target_schema[fragment]
44
+ end
45
+ fragment_path = fragment_path + "/#{fragment}"
46
+ if target_schema.nil?
47
+ raise SchemaError.new("The fragment '#{fragment_path}' does not exist on schema #{ref_schema.uri.to_s}")
48
+ end
49
+ end
50
+ end
51
+
52
+ # We have the schema finally, build it and validate!
53
+ uri = temp_uri
54
+ schema = JSON::Schema.new(target_schema,temp_uri,validator)
55
+ end
56
+
57
+ [uri,schema]
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,28 @@
1
+ require 'json-schema/attribute'
2
+
3
+ module JSON
4
+ class Schema
5
+ class RequiredAttribute < Attribute
6
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
7
+ return unless data.is_a?(Hash)
8
+
9
+ schema = current_schema.schema
10
+ defined_properties = schema['properties']
11
+
12
+ schema['required'].each do |property, property_schema|
13
+ next if data.has_key?(property.to_s)
14
+ prop_defaults = options[:insert_defaults] &&
15
+ defined_properties &&
16
+ defined_properties[property] &&
17
+ !defined_properties[property]["default"].nil? &&
18
+ !defined_properties[property]["readonly"]
19
+
20
+ if !prop_defaults
21
+ message = "The property '#{build_fragment(fragments)}' did not contain a required property of '#{property}'"
22
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,73 @@
1
+ require 'json-schema/attribute'
2
+
3
+ module JSON
4
+ class Schema
5
+ class TypeAttribute < Attribute
6
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
7
+ union = true
8
+ if options[:disallow]
9
+ types = current_schema.schema['disallow']
10
+ else
11
+ types = current_schema.schema['type']
12
+ end
13
+
14
+ if !types.is_a?(Array)
15
+ types = [types]
16
+ union = false
17
+ end
18
+ valid = false
19
+
20
+ # Create a hash to hold errors that are generated during union validation
21
+ union_errors = Hash.new { |hsh, k| hsh[k] = [] }
22
+
23
+ types.each_with_index do |type, type_index|
24
+ if type.is_a?(String)
25
+ valid = data_valid_for_type?(data, type)
26
+ elsif type.is_a?(Hash) && union
27
+ # Validate as a schema
28
+ schema = JSON::Schema.new(type,current_schema.uri,validator)
29
+
30
+ # We're going to add a little cruft here to try and maintain any validation errors that occur in this union type
31
+ # We'll handle this by keeping an error count before and after validation, extracting those errors and pushing them onto a union error
32
+ pre_validation_error_count = validation_errors(processor).count
33
+
34
+ begin
35
+ schema.validate(data,fragments,processor,options.merge(:disallow => false))
36
+ valid = true
37
+ rescue ValidationError
38
+ # We don't care that these schemas don't validate - we only care that one validated
39
+ end
40
+
41
+ diff = validation_errors(processor).count - pre_validation_error_count
42
+ valid = false if diff > 0
43
+ while diff > 0
44
+ diff = diff - 1
45
+ union_errors["type ##{type_index}"].push(validation_errors(processor).pop)
46
+ end
47
+ end
48
+
49
+ break if valid
50
+ end
51
+
52
+ if options[:disallow]
53
+ return if !valid
54
+ message = "The property '#{build_fragment(fragments)}' matched one or more of the following types: #{list_types(types)}"
55
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
56
+ elsif !valid
57
+ if union
58
+ message = "The property '#{build_fragment(fragments)}' of type #{type_of_data(data)} did not match one or more of the following types: #{list_types(types)}"
59
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
60
+ validation_errors(processor).last.sub_errors = union_errors
61
+ else
62
+ message = "The property '#{build_fragment(fragments)}' of type #{type_of_data(data)} did not match the following type: #{list_types(types)}"
63
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
64
+ end
65
+ end
66
+ end
67
+
68
+ def self.list_types(types)
69
+ types.map { |type| type.is_a?(String) ? type : '(schema)' }.join(', ')
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,29 @@
1
+ require 'json-schema/attribute'
2
+
3
+ module JSON
4
+ class Schema
5
+ class TypeV4Attribute < Attribute
6
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
7
+ union = true
8
+ types = current_schema.schema['type']
9
+ if !types.is_a?(Array)
10
+ types = [types]
11
+ union = false
12
+ end
13
+
14
+ return if types.any? { |type| data_valid_for_type?(data, type) }
15
+
16
+ types = types.map { |type| type.is_a?(String) ? type : '(schema)' }.join(', ')
17
+ message = format(
18
+ "The property '%s' of type %s did not match %s: %s",
19
+ build_fragment(fragments),
20
+ type_of_data(data),
21
+ union ? 'one or more of the following types' : 'the following type',
22
+ types
23
+ )
24
+
25
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,20 @@
1
+ require 'json-schema/attribute'
2
+
3
+ module JSON
4
+ class Schema
5
+ class UniqueItemsAttribute < Attribute
6
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
7
+ return unless data.is_a?(Array)
8
+
9
+ if data.clone.uniq!
10
+ message = "The property '#{build_fragment(fragments)}' contained duplicated array values"
11
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
12
+ end
13
+ end
14
+
15
+ def self.validate_on_false?
16
+ false
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,6 @@
1
+ module JSON
2
+ class Schema
3
+ class CustomFormatError < StandardError
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module JSON
2
+ class Schema
3
+ class JsonLoadError < StandardError
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module JSON
2
+ class Schema
3
+ class JsonParseError < StandardError
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module JSON
2
+ class Schema
3
+ class SchemaError < StandardError
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,8 @@
1
+ require 'json/common'
2
+
3
+ module JSON
4
+ class Schema
5
+ class SchemaParseError < JSON::ParserError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,6 @@
1
+ module JSON
2
+ class Schema
3
+ class UriError < StandardError
4
+ end
5
+ end
6
+ end