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,39 @@
1
+ require 'json-schema/attribute'
2
+
3
+ module JSON
4
+ class Schema
5
+ class AllOfAttribute < Attribute
6
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
7
+ # Create an hash to hold errors that are generated during validation
8
+ errors = Hash.new { |hsh, k| hsh[k] = [] }
9
+ valid = true
10
+
11
+ current_schema.schema['allOf'].each_with_index do |element, schema_index|
12
+ schema = JSON::Schema.new(element,current_schema.uri,validator)
13
+
14
+ # We're going to add a little cruft here to try and maintain any validation errors that occur in the allOf
15
+ # We'll handle this by keeping an error count before and after validation, extracting those errors and pushing them onto an error array
16
+ pre_validation_error_count = validation_errors(processor).count
17
+
18
+ begin
19
+ schema.validate(data,fragments,processor,options)
20
+ rescue ValidationError
21
+ valid = false
22
+ end
23
+
24
+ diff = validation_errors(processor).count - pre_validation_error_count
25
+ while diff > 0
26
+ diff = diff - 1
27
+ errors["allOf ##{schema_index}"].push(validation_errors(processor).pop)
28
+ end
29
+ end
30
+
31
+ if !valid || !errors.empty?
32
+ message = "The property '#{build_fragment(fragments)}' of type #{type_of_data(data)} did not match all of the required schemas"
33
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
34
+ validation_errors(processor).last.sub_errors = errors
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,47 @@
1
+ require 'json-schema/attribute'
2
+
3
+ module JSON
4
+ class Schema
5
+ class AnyOfAttribute < Attribute
6
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
7
+ # Create a hash to hold errors that are generated during validation
8
+ errors = Hash.new { |hsh, k| hsh[k] = [] }
9
+ valid = false
10
+
11
+ original_data = data.is_a?(Hash) ? data.clone : data
12
+
13
+ current_schema.schema['anyOf'].each_with_index do |element, schema_index|
14
+ schema = JSON::Schema.new(element,current_schema.uri,validator)
15
+
16
+ # We're going to add a little cruft here to try and maintain any validation errors that occur in the anyOf
17
+ # We'll handle this by keeping an error count before and after validation, extracting those errors and pushing them onto a union error
18
+ pre_validation_error_count = validation_errors(processor).count
19
+
20
+ begin
21
+ schema.validate(data,fragments,processor,options)
22
+ valid = true
23
+ rescue ValidationError
24
+ # We don't care that these schemas don't validate - we only care that one validated
25
+ end
26
+
27
+ diff = validation_errors(processor).count - pre_validation_error_count
28
+ valid = false if diff > 0
29
+ while diff > 0
30
+ diff = diff - 1
31
+ errors["anyOf ##{schema_index}"].push(validation_errors(processor).pop)
32
+ end
33
+
34
+ break if valid
35
+
36
+ data = original_data
37
+ end
38
+
39
+ if !valid
40
+ message = "The property '#{build_fragment(fragments)}' of type #{type_of_data(data)} did not match one or more of the required schemas"
41
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
42
+ validation_errors(processor).last.sub_errors = errors
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,38 @@
1
+ require 'json-schema/attribute'
2
+
3
+ module JSON
4
+ class Schema
5
+ class DependenciesAttribute < Attribute
6
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
7
+ return unless data.is_a?(Hash)
8
+
9
+ current_schema.schema['dependencies'].each do |property, dependency_value|
10
+ next unless data.has_key?(property.to_s)
11
+ next unless accept_value?(dependency_value)
12
+
13
+ case dependency_value
14
+ when String
15
+ validate_dependency(current_schema, data, property, dependency_value, fragments, processor, self, options)
16
+ when Array
17
+ dependency_value.each do |value|
18
+ validate_dependency(current_schema, data, property, value, fragments, processor, self, options)
19
+ end
20
+ else
21
+ schema = JSON::Schema.new(dependency_value, current_schema.uri, validator)
22
+ schema.validate(data, fragments, processor, options)
23
+ end
24
+ end
25
+ end
26
+
27
+ def self.validate_dependency(schema, data, property, value, fragments, processor, attribute, options)
28
+ return if data.key?(value.to_s)
29
+ message = "The property '#{build_fragment(fragments)}' has a property '#{property}' that depends on a missing property '#{value}'"
30
+ validation_error(processor, message, fragments, schema, attribute, options[:record_errors])
31
+ end
32
+
33
+ def self.accept_value?(value)
34
+ value.is_a?(String) || value.is_a?(Array) || value.is_a?(Hash)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,11 @@
1
+ require 'json-schema/attributes/dependencies'
2
+
3
+ module JSON
4
+ class Schema
5
+ class DependenciesV4Attribute < DependenciesAttribute
6
+ def self.accept_value?(value)
7
+ value.is_a?(Array) || value.is_a?(Hash)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ require 'json-schema/attribute'
2
+
3
+ module JSON
4
+ class Schema
5
+ class DisallowAttribute < Attribute
6
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
7
+ return unless type = validator.attributes['type']
8
+ type.validate(current_schema, data, fragments, processor, validator, options.merge(:disallow => true))
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,22 @@
1
+ require 'json-schema/attribute'
2
+
3
+ module JSON
4
+ class Schema
5
+ class DivisibleByAttribute < Attribute
6
+ def self.keyword
7
+ 'divisibleBy'
8
+ end
9
+
10
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
11
+ return unless data.is_a?(Numeric)
12
+
13
+ factor = current_schema.schema[keyword]
14
+
15
+ if factor == 0 || factor == 0.0 || (BigDecimal(data.to_s) % BigDecimal(factor.to_s)).to_f != 0
16
+ message = "The property '#{build_fragment(fragments)}' was not divisible by #{factor}"
17
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,24 @@
1
+ require 'json-schema/attribute'
2
+
3
+ module JSON
4
+ class Schema
5
+ class EnumAttribute < Attribute
6
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
7
+ enum = current_schema.schema['enum']
8
+ return if enum.include?(data)
9
+
10
+ values = enum.map { |val|
11
+ case val
12
+ when nil then 'null'
13
+ when Array then 'array'
14
+ when Hash then 'object'
15
+ else val.to_s
16
+ end
17
+ }.join(', ')
18
+
19
+ message = "The property '#{build_fragment(fragments)}' value #{data.inspect} did not match one of the following values: #{values}"
20
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,48 @@
1
+ require 'json-schema/attribute'
2
+ require 'json-schema/attributes/ref'
3
+
4
+ module JSON
5
+ class Schema
6
+ class ExtendsAttribute < Attribute
7
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
8
+ schemas = current_schema.schema['extends']
9
+ schemas = [schemas] if !schemas.is_a?(Array)
10
+ schemas.each do |s|
11
+ uri,schema = get_extended_uri_and_schema(s, current_schema, validator)
12
+ if schema
13
+ schema.validate(data, fragments, processor, options)
14
+ elsif uri
15
+ message = "The extended schema '#{uri.to_s}' cannot be found"
16
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
17
+ else
18
+ message = "The property '#{build_fragment(fragments)}' was not a valid schema"
19
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
20
+ end
21
+ end
22
+ end
23
+
24
+ def self.get_extended_uri_and_schema(s, current_schema, validator)
25
+ uri,schema = nil,nil
26
+
27
+ if s.is_a?(Hash)
28
+ uri = current_schema.uri
29
+ if s['$ref']
30
+ ref_uri,ref_schema = JSON::Schema::RefAttribute.get_referenced_uri_and_schema(s, current_schema, validator)
31
+ if ref_schema
32
+ if s.size == 1 # Check if anything else apart from $ref
33
+ uri,schema = ref_uri,ref_schema
34
+ else
35
+ s = s.dup
36
+ s.delete '$ref'
37
+ s = ref_schema.schema.merge(s)
38
+ end
39
+ end
40
+ end
41
+ schema ||= JSON::Schema.new(s,uri,validator)
42
+ end
43
+
44
+ [uri,schema]
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,14 @@
1
+ require 'json-schema/attribute'
2
+
3
+ module JSON
4
+ class Schema
5
+ class FormatAttribute < Attribute
6
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
7
+ return unless data_valid_for_type?(data, current_schema.schema['type'])
8
+ format = current_schema.schema['format'].to_s
9
+ validator = validator.formats[format]
10
+ validator.validate(current_schema, data, fragments, processor, validator, options) unless validator.nil?
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,21 @@
1
+ require 'json-schema/attributes/format'
2
+ require 'json-schema/errors/custom_format_error'
3
+
4
+ module JSON
5
+ class Schema
6
+ class CustomFormat < FormatAttribute
7
+ def initialize(validation_proc)
8
+ @validation_proc = validation_proc
9
+ end
10
+
11
+ def validate(current_schema, data, fragments, processor, validator, options = {})
12
+ begin
13
+ @validation_proc.call data
14
+ rescue JSON::Schema::CustomFormatError => e
15
+ message = "The property '#{self.class.build_fragment(fragments)}' #{e.message}"
16
+ self.class.validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,25 @@
1
+ require 'json-schema/attributes/format'
2
+
3
+ module JSON
4
+ class Schema
5
+ class DateFormat < FormatAttribute
6
+ REGEXP = /\A\d{4}-\d{2}-\d{2}\z/
7
+
8
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
9
+ if data.is_a?(String)
10
+ error_message = "The property '#{build_fragment(fragments)}' must be a date in the format of YYYY-MM-DD"
11
+ if REGEXP.match(data)
12
+ begin
13
+ Date.parse(data)
14
+ rescue ArgumentError => e
15
+ raise e unless e.message == 'invalid date'
16
+ validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
17
+ end
18
+ else
19
+ validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,34 @@
1
+ require 'json-schema/attributes/format'
2
+
3
+ module JSON
4
+ class Schema
5
+ class DateTimeFormat < FormatAttribute
6
+ REGEXP = /\A\d{4}-\d{2}-\d{2}T(\d{2}):(\d{2}):(\d{2})([\.,]\d+)?(Z|[+-](\d{2})(:?\d{2})?)?\z/
7
+
8
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
9
+ # Timestamp in restricted ISO-8601 YYYY-MM-DDThh:mm:ssZ with optional decimal fraction of the second
10
+ if data.is_a?(String)
11
+ error_message = "The property '#{build_fragment(fragments)}' must be a date/time in the ISO-8601 format of YYYY-MM-DDThh:mm:ssZ or YYYY-MM-DDThh:mm:ss.ssZ"
12
+ if (m = REGEXP.match(data))
13
+ parts = data.split("T")
14
+
15
+ begin
16
+ Date.parse(parts[0])
17
+ rescue ArgumentError => e
18
+ raise e unless e.message == 'invalid date'
19
+ validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
20
+ return
21
+ end
22
+
23
+ validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if m.length < 4
24
+ validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if m[1].to_i > 23
25
+ validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if m[2].to_i > 59
26
+ validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if m[3].to_i > 59
27
+ else
28
+ validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,15 @@
1
+ require 'json-schema/attributes/format'
2
+
3
+ module JSON
4
+ class Schema
5
+ class DateTimeV4Format < FormatAttribute
6
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
7
+ return unless data.is_a?(String)
8
+ DateTime.rfc3339(data)
9
+ rescue ArgumentError
10
+ error_message = "The property '#{build_fragment(fragments)}' must be a valid RFC3339 date/time string"
11
+ validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
12
+ end
13
+ end
14
+ end
15
+ end
@@ -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
@@ -0,0 +1,22 @@
1
+ require 'json-schema/attributes/format'
2
+
3
+ module JSON
4
+ class Schema
5
+ class TimeFormat < FormatAttribute
6
+ REGEXP = /\A(\d{2}):(\d{2}):(\d{2})\z/
7
+
8
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
9
+ if data.is_a?(String)
10
+ error_message = "The property '#{build_fragment(fragments)}' must be a time in the format of hh:mm:ss"
11
+ if (m = REGEXP.match(data))
12
+ validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if m[1].to_i > 23
13
+ validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if m[2].to_i > 59
14
+ validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if m[3].to_i > 59
15
+ else
16
+ validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,18 @@
1
+ require 'json-schema/attributes/format'
2
+ require 'json-schema/errors/uri_error'
3
+
4
+ module JSON
5
+ class Schema
6
+ class UriFormat < FormatAttribute
7
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
8
+ return unless data.is_a?(String)
9
+ error_message = "The property '#{build_fragment(fragments)}' must be a valid URI"
10
+ begin
11
+ JSON::Util::URI.parse(data)
12
+ rescue JSON::Schema::UriError
13
+ validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ require 'json-schema/attribute'
2
+
3
+ module JSON
4
+ class Schema
5
+ class ItemsAttribute < Attribute
6
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
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
+ break if i >= data.length
20
+ schema = JSON::Schema.new(item_schema, current_schema.uri, validator)
21
+ schema.validate(data[i], fragments + [i.to_s], processor, options)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,52 @@
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
+ end
52
+ end
@@ -0,0 +1,15 @@
1
+ require 'json-schema/attributes/limit'
2
+
3
+ module JSON
4
+ class Schema
5
+ class ItemsLimitAttribute < LimitAttribute
6
+ def self.acceptable_type
7
+ Array
8
+ end
9
+
10
+ def self.value(data)
11
+ data.length
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'json-schema/attributes/limit'
2
+
3
+ module JSON
4
+ class Schema
5
+ class LengthLimitAttribute < LimitAttribute
6
+ def self.acceptable_type
7
+ String
8
+ end
9
+
10
+ def self.value(data)
11
+ data.length
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'json-schema/attributes/limits/items'
2
+
3
+ module JSON
4
+ class Schema
5
+ class MaxItemsAttribute < ItemsLimitAttribute
6
+ def self.limit_name
7
+ 'maxItems'
8
+ end
9
+
10
+ def self.error_message(schema)
11
+ "had more items than the allowed #{limit(schema)}"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'json-schema/attributes/limits/length'
2
+
3
+ module JSON
4
+ class Schema
5
+ class MaxLengthAttribute < LengthLimitAttribute
6
+ def self.limit_name
7
+ 'maxLength'
8
+ end
9
+
10
+ def self.error_message(schema)
11
+ "was not of a maximum 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 MaxPropertiesAttribute < PropertiesLimitAttribute
6
+ def self.limit_name
7
+ 'maxProperties'
8
+ end
9
+
10
+ def self.error_message(schema)
11
+ "had more properties than the allowed #{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 MaximumAttribute < NumericLimitAttribute
6
+ def self.limit_name
7
+ 'maximum'
8
+ end
9
+
10
+ def self.exclusive?(schema)
11
+ schema['exclusiveMaximum']
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ require 'json-schema/attributes/limits/maximum'
2
+
3
+ module JSON
4
+ class Schema
5
+ class MaximumInclusiveAttribute < MaximumAttribute
6
+ def self.exclusive?(schema)
7
+ schema['maximumCanEqual'] == false
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ require 'json-schema/attributes/limits/items'
2
+
3
+ module JSON
4
+ class Schema
5
+ class MinItemsAttribute < ItemsLimitAttribute
6
+ def self.limit_name
7
+ 'minItems'
8
+ end
9
+
10
+ def self.error_message(schema)
11
+ "did not contain a minimum number of items #{limit(schema)}"
12
+ end
13
+ end
14
+ end
15
+ end