json-schema 3.0.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -1
- data/lib/json-schema/attribute.rb +13 -14
- data/lib/json-schema/attributes/additionalitems.rb +1 -0
- data/lib/json-schema/attributes/additionalproperties.rb +3 -6
- data/lib/json-schema/attributes/allof.rb +2 -2
- data/lib/json-schema/attributes/anyof.rb +2 -2
- data/lib/json-schema/attributes/dependencies.rb +1 -0
- data/lib/json-schema/attributes/disallow.rb +2 -1
- data/lib/json-schema/attributes/enum.rb +2 -2
- data/lib/json-schema/attributes/extends.rb +6 -6
- data/lib/json-schema/attributes/format.rb +2 -1
- data/lib/json-schema/attributes/formats/date.rb +1 -0
- data/lib/json-schema/attributes/formats/date_time.rb +2 -1
- data/lib/json-schema/attributes/formats/date_time_v4.rb +1 -0
- data/lib/json-schema/attributes/formats/uri.rb +1 -0
- data/lib/json-schema/attributes/items.rb +1 -0
- data/lib/json-schema/attributes/limits/numeric.rb +1 -1
- data/lib/json-schema/attributes/maxdecimal.rb +1 -1
- data/lib/json-schema/attributes/not.rb +2 -2
- data/lib/json-schema/attributes/oneof.rb +2 -4
- data/lib/json-schema/attributes/patternproperties.rb +1 -0
- data/lib/json-schema/attributes/properties.rb +4 -4
- data/lib/json-schema/attributes/propertynames.rb +23 -0
- data/lib/json-schema/attributes/ref.rb +7 -7
- data/lib/json-schema/attributes/required.rb +3 -2
- data/lib/json-schema/attributes/type.rb +3 -2
- data/lib/json-schema/attributes/type_v4.rb +1 -1
- data/lib/json-schema/errors/validation_error.rb +4 -5
- data/lib/json-schema/schema/reader.rb +2 -0
- data/lib/json-schema/schema/validator.rb +3 -3
- data/lib/json-schema/schema.rb +3 -4
- data/lib/json-schema/util/array_set.rb +1 -1
- data/lib/json-schema/util/uri.rb +7 -7
- data/lib/json-schema/util/uuid.rb +227 -226
- data/lib/json-schema/validator.rb +84 -82
- data/lib/json-schema/validators/draft1.rb +21 -23
- data/lib/json-schema/validators/draft2.rb +22 -24
- data/lib/json-schema/validators/draft3.rb +26 -28
- data/lib/json-schema/validators/draft4.rb +34 -36
- data/lib/json-schema/validators/draft6.rb +36 -37
- data/lib/json-schema/validators/hyper-draft1.rb +2 -3
- data/lib/json-schema/validators/hyper-draft2.rb +2 -3
- data/lib/json-schema/validators/hyper-draft3.rb +2 -3
- data/lib/json-schema/validators/hyper-draft4.rb +2 -3
- data/lib/json-schema/validators/hyper-draft6.rb +2 -3
- data/lib/json-schema.rb +2 -2
- data/resources/draft-06.json +12 -12
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3685239fb43fca88ffbeb8fe2f220b1b6a53e8ab8b367c51d3bd55526388d75d
|
4
|
+
data.tar.gz: dcfbf33b0a3f33b0c193e441430d85714f7ffc75deb5ce0d466a32d6dbb91b0a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c6e9352ea89263e330481b725e9900fba6a4ae215ce2bc08772626e7282e3c9a279b1590f1d5209825d837a465b034c4128bc8ccbd4d31767e029575eb973ac1
|
7
|
+
data.tar.gz: 16be5e3ec637f8a7ecfbcdcf984beb862f9ca540a1faac84b9f6b596d3ee0e9b1ff86dc5a6e83f4bf7b3573f052566384491d1d7f7361a37720417cb7a5e91f0
|
data/README.md
CHANGED
@@ -9,7 +9,8 @@
|
|
9
9
|
|
10
10
|
This library is intended to provide Ruby with an interface for validating JSON
|
11
11
|
objects against a JSON schema conforming to [JSON Schema Draft
|
12
|
-
|
12
|
+
6](https://tools.ietf.org/html/draft-wright-json-schema-01). Legacy support for
|
13
|
+
[JSON Schema Draft 4](http://tools.ietf.org/html/draft-zyp-json-schema-04),
|
13
14
|
[JSON Schema Draft 3](http://tools.ietf.org/html/draft-zyp-json-schema-03),
|
14
15
|
[JSON Schema Draft 2](http://tools.ietf.org/html/draft-zyp-json-schema-02), and
|
15
16
|
[JSON Schema Draft 1](http://tools.ietf.org/html/draft-zyp-json-schema-01) is
|
@@ -3,8 +3,7 @@ require 'json-schema/errors/validation_error'
|
|
3
3
|
module JSON
|
4
4
|
class Schema
|
5
5
|
class Attribute
|
6
|
-
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
7
|
-
end
|
6
|
+
def self.validate(current_schema, data, fragments, processor, validator, options = {}); end
|
8
7
|
|
9
8
|
def self.build_fragment(fragments)
|
10
9
|
"#/#{fragments.join('/')}"
|
@@ -24,14 +23,14 @@ module JSON
|
|
24
23
|
end
|
25
24
|
|
26
25
|
TYPE_CLASS_MAPPINGS = {
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
26
|
+
'string' => String,
|
27
|
+
'number' => Numeric,
|
28
|
+
'integer' => Integer,
|
29
|
+
'boolean' => [TrueClass, FalseClass],
|
30
|
+
'object' => Hash,
|
31
|
+
'array' => Array,
|
32
|
+
'null' => NilClass,
|
33
|
+
'any' => Object,
|
35
34
|
}
|
36
35
|
|
37
36
|
def self.data_valid_for_type?(data, type)
|
@@ -41,11 +40,11 @@ module JSON
|
|
41
40
|
|
42
41
|
# Lookup Schema type of given class instance
|
43
42
|
def self.type_of_data(data)
|
44
|
-
type,
|
43
|
+
type, = TYPE_CLASS_MAPPINGS.map { |k, v| [k, v] }.sort_by do |(_, v)|
|
45
44
|
-Array(v).map { |klass| klass.ancestors.size }.max
|
46
|
-
|
47
|
-
Array(v).any? { |klass| data.
|
48
|
-
|
45
|
+
end.find do |(_, v)|
|
46
|
+
Array(v).any? { |klass| data.is_a?(klass) }
|
47
|
+
end
|
49
48
|
type
|
50
49
|
end
|
51
50
|
end
|
@@ -19,6 +19,7 @@ module JSON
|
|
19
19
|
additional_items_schema = JSON::Schema.new(schema['additionalItems'], current_schema.uri, validator)
|
20
20
|
data.each_with_index do |item, i|
|
21
21
|
next if i < schema['items'].length
|
22
|
+
|
22
23
|
additional_items_schema.validate(item, fragments + [i.to_s], processor, options)
|
23
24
|
end
|
24
25
|
end
|
@@ -33,11 +33,9 @@ module JSON
|
|
33
33
|
extra_properties = extra_properties - schema['properties'].keys
|
34
34
|
end
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
extra_properties.reject! { |prop| regexp.match(prop) }
|
40
|
-
end
|
36
|
+
schema['patternProperties']&.each_key do |key|
|
37
|
+
regexp = Regexp.new(key)
|
38
|
+
extra_properties.reject! { |prop| regexp.match(prop) }
|
41
39
|
end
|
42
40
|
|
43
41
|
if extended_schemas = schema['extends']
|
@@ -52,7 +50,6 @@ module JSON
|
|
52
50
|
|
53
51
|
extra_properties
|
54
52
|
end
|
55
|
-
|
56
53
|
end
|
57
54
|
end
|
58
55
|
end
|
@@ -9,14 +9,14 @@ module JSON
|
|
9
9
|
valid = true
|
10
10
|
|
11
11
|
current_schema.schema['allOf'].each_with_index do |element, schema_index|
|
12
|
-
schema = JSON::Schema.new(element,current_schema.uri,validator)
|
12
|
+
schema = JSON::Schema.new(element, current_schema.uri, validator)
|
13
13
|
|
14
14
|
# We're going to add a little cruft here to try and maintain any validation errors that occur in the allOf
|
15
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
16
|
pre_validation_error_count = validation_errors(processor).count
|
17
17
|
|
18
18
|
begin
|
19
|
-
schema.validate(data,fragments,processor,options)
|
19
|
+
schema.validate(data, fragments, processor, options)
|
20
20
|
rescue ValidationError
|
21
21
|
valid = false
|
22
22
|
end
|
@@ -11,14 +11,14 @@ module JSON
|
|
11
11
|
original_data = data.is_a?(Hash) ? data.clone : data
|
12
12
|
|
13
13
|
current_schema.schema['anyOf'].each_with_index do |element, schema_index|
|
14
|
-
schema = JSON::Schema.new(element,current_schema.uri,validator)
|
14
|
+
schema = JSON::Schema.new(element, current_schema.uri, validator)
|
15
15
|
|
16
16
|
# We're going to add a little cruft here to try and maintain any validation errors that occur in the anyOf
|
17
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
18
|
pre_validation_error_count = validation_errors(processor).count
|
19
19
|
|
20
20
|
begin
|
21
|
-
schema.validate(data,fragments,processor,options)
|
21
|
+
schema.validate(data, fragments, processor, options)
|
22
22
|
valid = true
|
23
23
|
rescue ValidationError
|
24
24
|
# We don't care that these schemas don't validate - we only care that one validated
|
@@ -26,6 +26,7 @@ module JSON
|
|
26
26
|
|
27
27
|
def self.validate_dependency(schema, data, property, value, fragments, processor, attribute, options)
|
28
28
|
return if data.key?(value.to_s)
|
29
|
+
|
29
30
|
message = "The property '#{build_fragment(fragments)}' has a property '#{property}' that depends on a missing property '#{value}'"
|
30
31
|
validation_error(processor, message, fragments, schema, attribute, options[:record_errors])
|
31
32
|
end
|
@@ -5,7 +5,8 @@ module JSON
|
|
5
5
|
class DisallowAttribute < Attribute
|
6
6
|
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
7
7
|
return unless type = validator.attributes['type']
|
8
|
-
|
8
|
+
|
9
|
+
type.validate(current_schema, data, fragments, processor, validator, options.merge(disallow: true))
|
9
10
|
end
|
10
11
|
end
|
11
12
|
end
|
@@ -7,14 +7,14 @@ module JSON
|
|
7
7
|
enum = current_schema.schema['enum']
|
8
8
|
return if enum.include?(data)
|
9
9
|
|
10
|
-
values = enum.map
|
10
|
+
values = enum.map do |val|
|
11
11
|
case val
|
12
12
|
when nil then 'null'
|
13
13
|
when Array then 'array'
|
14
14
|
when Hash then 'object'
|
15
15
|
else val.to_s
|
16
16
|
end
|
17
|
-
|
17
|
+
end.join(', ')
|
18
18
|
|
19
19
|
message = "The property '#{build_fragment(fragments)}' value #{data.inspect} did not match one of the following values: #{values}"
|
20
20
|
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
|
@@ -8,7 +8,7 @@ module JSON
|
|
8
8
|
schemas = current_schema.schema['extends']
|
9
9
|
schemas = [schemas] if !schemas.is_a?(Array)
|
10
10
|
schemas.each do |s|
|
11
|
-
uri,schema = get_extended_uri_and_schema(s, current_schema, validator)
|
11
|
+
uri, schema = get_extended_uri_and_schema(s, current_schema, validator)
|
12
12
|
if schema
|
13
13
|
schema.validate(data, fragments, processor, options)
|
14
14
|
elsif uri
|
@@ -22,15 +22,15 @@ module JSON
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def self.get_extended_uri_and_schema(s, current_schema, validator)
|
25
|
-
uri,schema = nil,nil
|
25
|
+
uri, schema = nil, nil
|
26
26
|
|
27
27
|
if s.is_a?(Hash)
|
28
28
|
uri = current_schema.uri
|
29
29
|
if s['$ref']
|
30
|
-
ref_uri,ref_schema = JSON::Schema::RefAttribute.get_referenced_uri_and_schema(s, current_schema, validator)
|
30
|
+
ref_uri, ref_schema = JSON::Schema::RefAttribute.get_referenced_uri_and_schema(s, current_schema, validator)
|
31
31
|
if ref_schema
|
32
32
|
if s.size == 1 # Check if anything else apart from $ref
|
33
|
-
uri,schema = ref_uri,ref_schema
|
33
|
+
uri, schema = ref_uri, ref_schema
|
34
34
|
else
|
35
35
|
s = s.dup
|
36
36
|
s.delete '$ref'
|
@@ -38,10 +38,10 @@ module JSON
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
41
|
-
schema ||= JSON::Schema.new(s,uri,validator)
|
41
|
+
schema ||= JSON::Schema.new(s, uri, validator)
|
42
42
|
end
|
43
43
|
|
44
|
-
[uri,schema]
|
44
|
+
[uri, schema]
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
@@ -5,9 +5,10 @@ module JSON
|
|
5
5
|
class FormatAttribute < Attribute
|
6
6
|
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
7
7
|
return unless data_valid_for_type?(data, current_schema.schema['type'])
|
8
|
+
|
8
9
|
format = current_schema.schema['format'].to_s
|
9
10
|
validator = validator.formats[format]
|
10
|
-
validator
|
11
|
+
validator&.validate(current_schema, data, fragments, processor, validator, options)
|
11
12
|
end
|
12
13
|
end
|
13
14
|
end
|
@@ -10,12 +10,13 @@ module JSON
|
|
10
10
|
if data.is_a?(String)
|
11
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
12
|
if (m = REGEXP.match(data))
|
13
|
-
parts = data.split(
|
13
|
+
parts = data.split('T')
|
14
14
|
|
15
15
|
begin
|
16
16
|
Date.parse(parts[0])
|
17
17
|
rescue ArgumentError => e
|
18
18
|
raise e unless e.message == 'invalid date'
|
19
|
+
|
19
20
|
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
|
20
21
|
return
|
21
22
|
end
|
@@ -5,6 +5,7 @@ module JSON
|
|
5
5
|
class DateTimeV4Format < FormatAttribute
|
6
6
|
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
7
7
|
return unless data.is_a?(String)
|
8
|
+
|
8
9
|
DateTime.rfc3339(data)
|
9
10
|
rescue ArgumentError
|
10
11
|
error_message = "The property '#{build_fragment(fragments)}' must be a valid RFC3339 date/time string"
|
@@ -6,6 +6,7 @@ module JSON
|
|
6
6
|
class UriFormat < FormatAttribute
|
7
7
|
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
8
8
|
return unless data.is_a?(String)
|
9
|
+
|
9
10
|
error_message = "The property '#{build_fragment(fragments)}' must be a valid URI"
|
10
11
|
begin
|
11
12
|
JSON::Util::URI.parse(data)
|
@@ -9,7 +9,7 @@ module JSON
|
|
9
9
|
|
10
10
|
def self.error_message(schema)
|
11
11
|
exclusivity = exclusive?(schema) ? 'exclusively' : 'inclusively'
|
12
|
-
format(
|
12
|
+
format('did not have a %s value of %s, %s', limit_name, limit(schema), exclusivity)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -7,7 +7,7 @@ module JSON
|
|
7
7
|
return unless data.is_a?(Numeric)
|
8
8
|
|
9
9
|
max_decimal_places = current_schema.schema['maxDecimal']
|
10
|
-
s = data.to_s.split(
|
10
|
+
s = data.to_s.split('.')[1]
|
11
11
|
if s && s.length > max_decimal_places
|
12
12
|
message = "The property '#{build_fragment(fragments)}' had more decimal places than the allowed #{max_decimal_places}"
|
13
13
|
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
|
@@ -4,12 +4,12 @@ module JSON
|
|
4
4
|
class Schema
|
5
5
|
class NotAttribute < Attribute
|
6
6
|
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
7
|
-
schema = JSON::Schema.new(current_schema.schema['not'],current_schema.uri,validator)
|
7
|
+
schema = JSON::Schema.new(current_schema.schema['not'], current_schema.uri, validator)
|
8
8
|
failed = true
|
9
9
|
errors_copy = processor.validation_errors.clone
|
10
10
|
|
11
11
|
begin
|
12
|
-
schema.validate(data,fragments,processor,options)
|
12
|
+
schema.validate(data, fragments, processor, options)
|
13
13
|
# If we're recording errors, we don't throw an exception. Instead, check the errors array length
|
14
14
|
if options[:record_errors] && errors_copy.length != processor.validation_errors.length
|
15
15
|
processor.validation_errors.replace(errors_copy)
|
@@ -15,10 +15,10 @@ module JSON
|
|
15
15
|
valid = false
|
16
16
|
|
17
17
|
one_of.each_with_index do |element, schema_index|
|
18
|
-
schema = JSON::Schema.new(element,current_schema.uri,validator)
|
18
|
+
schema = JSON::Schema.new(element, current_schema.uri, validator)
|
19
19
|
pre_validation_error_count = validation_errors(processor).count
|
20
20
|
begin
|
21
|
-
schema.validate(data,fragments,processor,options)
|
21
|
+
schema.validate(data, fragments, processor, options)
|
22
22
|
success_data = data.is_a?(Hash) ? data.clone : data
|
23
23
|
valid = true
|
24
24
|
rescue ValidationError
|
@@ -35,8 +35,6 @@ module JSON
|
|
35
35
|
data = original_data
|
36
36
|
end
|
37
37
|
|
38
|
-
|
39
|
-
|
40
38
|
if validation_error_count == one_of.length - 1
|
41
39
|
data = success_data
|
42
40
|
return
|
@@ -12,6 +12,7 @@ module JSON
|
|
12
12
|
# Check each key in the data hash to see if it matches the regex
|
13
13
|
data.each do |key, value|
|
14
14
|
next unless regexp.match(key)
|
15
|
+
|
15
16
|
schema = JSON::Schema.new(property_schema, current_schema.uri, validator)
|
16
17
|
schema.validate(data[key], fragments + [key], processor, options)
|
17
18
|
end
|
@@ -15,9 +15,9 @@ module JSON
|
|
15
15
|
property = property.to_s
|
16
16
|
|
17
17
|
if !data.key?(property) &&
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
options[:insert_defaults] &&
|
19
|
+
property_schema.has_key?('default') &&
|
20
|
+
!property_schema['readonly']
|
21
21
|
default = property_schema['default']
|
22
22
|
data[property] = default.is_a?(Hash) ? default.clone : default
|
23
23
|
end
|
@@ -55,7 +55,7 @@ module JSON
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
-
|
58
|
+
unless diff.empty?
|
59
59
|
properties = diff.keys.join(', ')
|
60
60
|
message = "The property '#{build_fragment(fragments)}' contained undefined properties: '#{properties}'"
|
61
61
|
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'json-schema/attribute'
|
2
|
+
|
3
|
+
module JSON
|
4
|
+
class Schema
|
5
|
+
class PropertyNames < Attribute
|
6
|
+
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
7
|
+
return unless data.is_a?(Hash)
|
8
|
+
|
9
|
+
propnames = current_schema.schema['propertyNames']
|
10
|
+
|
11
|
+
if propnames.is_a?(Hash)
|
12
|
+
schema = JSON::Schema.new(propnames, current_schema.uri, validator)
|
13
|
+
data.each_key do |key|
|
14
|
+
schema.validate(key, fragments + [key], processor, options)
|
15
|
+
end
|
16
|
+
elsif propnames == false && data.any?
|
17
|
+
message = "The property '#{build_fragment(fragments)}' contains additional properties #{data.keys.inspect} outside of the schema when none are allowed"
|
18
|
+
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -6,7 +6,7 @@ module JSON
|
|
6
6
|
class Schema
|
7
7
|
class RefAttribute < Attribute
|
8
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)
|
9
|
+
uri, schema = get_referenced_uri_and_schema(current_schema.schema, current_schema, validator)
|
10
10
|
|
11
11
|
if schema
|
12
12
|
schema.validate(data, fragments, processor, options)
|
@@ -20,19 +20,19 @@ module JSON
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def self.get_referenced_uri_and_schema(s, current_schema, validator)
|
23
|
-
uri,schema = nil,nil
|
23
|
+
uri, schema = nil, nil
|
24
24
|
|
25
25
|
temp_uri = JSON::Util::URI.normalize_ref(s['$ref'], current_schema.uri)
|
26
26
|
|
27
27
|
# Grab the parent schema from the schema list
|
28
|
-
schema_key = temp_uri.to_s.split(
|
28
|
+
schema_key = temp_uri.to_s.split('#')[0] + '#'
|
29
29
|
|
30
30
|
ref_schema = JSON::Validator.schema_for_uri(schema_key)
|
31
31
|
|
32
32
|
if ref_schema
|
33
33
|
# Perform fragment resolution to retrieve the appropriate level for the schema
|
34
34
|
target_schema = ref_schema.schema
|
35
|
-
fragments = JSON::Util::URI.parse(JSON::Util::URI.unescape_uri(temp_uri)).fragment.split(
|
35
|
+
fragments = JSON::Util::URI.parse(JSON::Util::URI.unescape_uri(temp_uri)).fragment.split('/')
|
36
36
|
fragment_path = ''
|
37
37
|
fragments.each do |fragment|
|
38
38
|
if fragment && fragment != ''
|
@@ -44,17 +44,17 @@ module JSON
|
|
44
44
|
end
|
45
45
|
fragment_path = fragment_path + "/#{fragment}"
|
46
46
|
if target_schema.nil?
|
47
|
-
raise SchemaError
|
47
|
+
raise SchemaError, "The fragment '#{fragment_path}' does not exist on schema #{ref_schema.uri.to_s}"
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
52
|
# We have the schema finally, build it and validate!
|
53
53
|
uri = temp_uri
|
54
|
-
schema = JSON::Schema.new(target_schema,temp_uri,validator)
|
54
|
+
schema = JSON::Schema.new(target_schema, temp_uri, validator)
|
55
55
|
end
|
56
56
|
|
57
|
-
[uri,schema]
|
57
|
+
[uri, schema]
|
58
58
|
end
|
59
59
|
end
|
60
60
|
end
|
@@ -11,11 +11,12 @@ module JSON
|
|
11
11
|
|
12
12
|
schema['required'].each do |property, property_schema|
|
13
13
|
next if data.has_key?(property.to_s)
|
14
|
+
|
14
15
|
prop_defaults = options[:insert_defaults] &&
|
15
16
|
defined_properties &&
|
16
17
|
defined_properties[property] &&
|
17
|
-
!defined_properties[property][
|
18
|
-
!defined_properties[property][
|
18
|
+
!defined_properties[property]['default'].nil? &&
|
19
|
+
!defined_properties[property]['readonly']
|
19
20
|
|
20
21
|
if !prop_defaults
|
21
22
|
message = "The property '#{build_fragment(fragments)}' did not contain a required property of '#{property}'"
|
@@ -25,14 +25,14 @@ module JSON
|
|
25
25
|
valid = data_valid_for_type?(data, type)
|
26
26
|
elsif type.is_a?(Hash) && union
|
27
27
|
# Validate as a schema
|
28
|
-
schema = JSON::Schema.new(type,current_schema.uri,validator)
|
28
|
+
schema = JSON::Schema.new(type, current_schema.uri, validator)
|
29
29
|
|
30
30
|
# We're going to add a little cruft here to try and maintain any validation errors that occur in this union type
|
31
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
32
|
pre_validation_error_count = validation_errors(processor).count
|
33
33
|
|
34
34
|
begin
|
35
|
-
schema.validate(data,fragments,processor,options.merge(:
|
35
|
+
schema.validate(data, fragments, processor, options.merge(disallow: false))
|
36
36
|
valid = true
|
37
37
|
rescue ValidationError
|
38
38
|
# We don't care that these schemas don't validate - we only care that one validated
|
@@ -51,6 +51,7 @@ module JSON
|
|
51
51
|
|
52
52
|
if options[:disallow]
|
53
53
|
return if !valid
|
54
|
+
|
54
55
|
message = "The property '#{build_fragment(fragments)}' matched one or more of the following types: #{list_types(types)}"
|
55
56
|
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
|
56
57
|
elsif !valid
|
@@ -19,7 +19,7 @@ module JSON
|
|
19
19
|
build_fragment(fragments),
|
20
20
|
type_of_data(data),
|
21
21
|
union ? 'one or more of the following types' : 'the following type',
|
22
|
-
types
|
22
|
+
types,
|
23
23
|
)
|
24
24
|
|
25
25
|
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module JSON
|
2
2
|
class Schema
|
3
3
|
class ValidationError < StandardError
|
4
|
-
INDENT =
|
4
|
+
INDENT = ' '
|
5
5
|
attr_accessor :fragments, :schema, :failed_attribute, :sub_errors, :message
|
6
6
|
|
7
7
|
def initialize(message, fragments, failed_attribute, schema)
|
@@ -27,12 +27,11 @@ module JSON
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def to_hash
|
30
|
-
base = {:
|
30
|
+
base = { schema: @schema.uri, fragment: ::JSON::Schema::Attribute.build_fragment(fragments), message: message_with_schema, failed_attribute: @failed_attribute.to_s.split(':').last.split('Attribute').first }
|
31
31
|
if !@sub_errors.empty?
|
32
|
-
base[:errors] = @sub_errors.
|
32
|
+
base[:errors] = @sub_errors.each_with_object({}) do |(subschema, errors), hsh|
|
33
33
|
subschema_sym = subschema.downcase.gsub(/\W+/, '_').to_sym
|
34
|
-
hsh[subschema_sym] = Array(errors).map{|e| e.to_hash}
|
35
|
-
hsh
|
34
|
+
hsh[subschema_sym] = Array(errors).map { |e| e.to_hash }
|
36
35
|
end
|
37
36
|
end
|
38
37
|
base
|
@@ -28,6 +28,7 @@ module JSON
|
|
28
28
|
# a schema should not be read.
|
29
29
|
class ReadRefused < ReadError
|
30
30
|
private
|
31
|
+
|
31
32
|
def error_message
|
32
33
|
"Read of #{type_string} at #{location} refused"
|
33
34
|
end
|
@@ -36,6 +37,7 @@ module JSON
|
|
36
37
|
# Raised by {JSON::Schema::Reader} when an attempt to read a schema fails
|
37
38
|
class ReadFailed < ReadError
|
38
39
|
private
|
40
|
+
|
39
41
|
def error_message
|
40
42
|
"Read of #{type_string} at #{location} failed"
|
41
43
|
end
|
@@ -4,7 +4,7 @@ module JSON
|
|
4
4
|
attr_accessor :attributes, :formats, :uri, :names
|
5
5
|
attr_reader :default_formats
|
6
6
|
|
7
|
-
def initialize
|
7
|
+
def initialize
|
8
8
|
@attributes = {}
|
9
9
|
@formats = {}
|
10
10
|
@default_formats = {}
|
@@ -14,13 +14,13 @@ module JSON
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def extend_schema_definition(schema_uri)
|
17
|
-
warn
|
17
|
+
warn '[DEPRECATION NOTICE] The preferred way to extend a Validator is by subclassing, rather than #extend_schema_definition. This method will be removed in version >= 3.'
|
18
18
|
validator = JSON::Validator.validator_for_uri(schema_uri)
|
19
19
|
@attributes.merge!(validator.attributes)
|
20
20
|
end
|
21
21
|
|
22
22
|
def validate(current_schema, data, fragments, processor, options = {})
|
23
|
-
current_schema.schema.each do |attr_name,attribute|
|
23
|
+
current_schema.schema.each do |attr_name, attribute|
|
24
24
|
if @attributes.has_key?(attr_name.to_s)
|
25
25
|
@attributes[attr_name.to_s].validate(current_schema, data, fragments, processor, self, options)
|
26
26
|
end
|
data/lib/json-schema/schema.rb
CHANGED
@@ -2,15 +2,14 @@ require 'pathname'
|
|
2
2
|
|
3
3
|
module JSON
|
4
4
|
class Schema
|
5
|
-
|
6
5
|
attr_accessor :schema, :uri, :validator
|
7
6
|
|
8
|
-
def initialize(schema,uri,parent_validator=nil)
|
7
|
+
def initialize(schema, uri, parent_validator = nil)
|
9
8
|
@schema = schema
|
10
9
|
@uri = uri
|
11
10
|
|
12
11
|
# If there is an ID on this schema, use it to generate the URI
|
13
|
-
if @schema['id']
|
12
|
+
if @schema['id'].is_a?(String)
|
14
13
|
temp_uri = JSON::Util::URI.parse(@schema['id'])
|
15
14
|
if temp_uri.relative?
|
16
15
|
temp_uri = uri.join(temp_uri)
|
@@ -36,7 +35,7 @@ module JSON
|
|
36
35
|
def self.stringify(schema)
|
37
36
|
case schema
|
38
37
|
when Hash then
|
39
|
-
|
38
|
+
schema.map { |key, value| [key.to_s, stringify(schema[key])] }.to_h
|
40
39
|
when Array then
|
41
40
|
schema.map do |schema_item|
|
42
41
|
stringify(schema_item)
|
@@ -7,7 +7,7 @@ class ArraySet < Array
|
|
7
7
|
def include?(obj)
|
8
8
|
if !defined? @values
|
9
9
|
@values = Set.new
|
10
|
-
|
10
|
+
each { |x| @values << convert_to_float_if_numeric(x) }
|
11
11
|
end
|
12
12
|
@values.include?(convert_to_float_if_numeric(obj))
|
13
13
|
end
|