json-schema-pvdgm 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.md +19 -0
- data/README.textile +354 -0
- data/lib/json-schema.rb +25 -0
- data/lib/json-schema/attributes/additionalitems.rb +23 -0
- data/lib/json-schema/attributes/additionalproperties.rb +67 -0
- data/lib/json-schema/attributes/allof.rb +37 -0
- data/lib/json-schema/attributes/anyof.rb +41 -0
- data/lib/json-schema/attributes/dependencies.rb +30 -0
- data/lib/json-schema/attributes/dependencies_v4.rb +20 -0
- data/lib/json-schema/attributes/disallow.rb +11 -0
- data/lib/json-schema/attributes/divisibleby.rb +16 -0
- data/lib/json-schema/attributes/enum.rb +24 -0
- data/lib/json-schema/attributes/extends.rb +49 -0
- data/lib/json-schema/attributes/format.rb +123 -0
- data/lib/json-schema/attributes/items.rb +25 -0
- data/lib/json-schema/attributes/maxdecimal.rb +15 -0
- data/lib/json-schema/attributes/maximum.rb +15 -0
- data/lib/json-schema/attributes/maximum_inclusive.rb +15 -0
- data/lib/json-schema/attributes/maxitems.rb +12 -0
- data/lib/json-schema/attributes/maxlength.rb +14 -0
- data/lib/json-schema/attributes/maxproperties.rb +12 -0
- data/lib/json-schema/attributes/minimum.rb +15 -0
- data/lib/json-schema/attributes/minimum_inclusive.rb +15 -0
- data/lib/json-schema/attributes/minitems.rb +12 -0
- data/lib/json-schema/attributes/minlength.rb +14 -0
- data/lib/json-schema/attributes/minproperties.rb +12 -0
- data/lib/json-schema/attributes/multipleof.rb +16 -0
- data/lib/json-schema/attributes/not.rb +28 -0
- data/lib/json-schema/attributes/oneof.rb +32 -0
- data/lib/json-schema/attributes/pattern.rb +15 -0
- data/lib/json-schema/attributes/patternproperties.rb +23 -0
- data/lib/json-schema/attributes/properties.rb +58 -0
- data/lib/json-schema/attributes/properties_optional.rb +23 -0
- data/lib/json-schema/attributes/properties_v4.rb +57 -0
- data/lib/json-schema/attributes/ref.rb +70 -0
- data/lib/json-schema/attributes/required.rb +23 -0
- data/lib/json-schema/attributes/type.rb +102 -0
- data/lib/json-schema/attributes/type_v4.rb +54 -0
- data/lib/json-schema/attributes/uniqueitems.rb +16 -0
- data/lib/json-schema/model_validator.rb +85 -0
- data/lib/json-schema/schema.rb +73 -0
- data/lib/json-schema/uri/file.rb +36 -0
- data/lib/json-schema/uri/uuid.rb +285 -0
- data/lib/json-schema/util/array_set.rb +14 -0
- data/lib/json-schema/util/hash.rb +8 -0
- data/lib/json-schema/validator.rb +672 -0
- data/lib/json-schema/validators/draft1.rb +32 -0
- data/lib/json-schema/validators/draft2.rb +33 -0
- data/lib/json-schema/validators/draft3.rb +38 -0
- data/lib/json-schema/validators/draft4.rb +45 -0
- data/resources/draft-01.json +155 -0
- data/resources/draft-02.json +166 -0
- data/resources/draft-03.json +174 -0
- data/resources/draft-04.json +150 -0
- data/test/data/all_of_ref_data.json +3 -0
- data/test/data/any_of_ref_data.json +7 -0
- data/test/data/bad_data_1.json +3 -0
- data/test/data/good_data_1.json +3 -0
- data/test/data/one_of_ref_links_data.json +5 -0
- data/test/schemas/all_of_ref_base_schema.json +6 -0
- data/test/schemas/all_of_ref_schema.json +7 -0
- data/test/schemas/any_of_ref_jane_schema.json +4 -0
- data/test/schemas/any_of_ref_jimmy_schema.json +4 -0
- data/test/schemas/any_of_ref_john_schema.json +4 -0
- data/test/schemas/any_of_ref_schema.json +15 -0
- data/test/schemas/extends_and_additionalProperties-1-filename.schema.json +34 -0
- data/test/schemas/extends_and_additionalProperties-1-ref.schema.json +34 -0
- data/test/schemas/extends_and_additionalProperties-2-filename.schema.json +33 -0
- data/test/schemas/extends_and_additionalProperties-2-ref.schema.json +33 -0
- data/test/schemas/good_schema_1.json +10 -0
- data/test/schemas/good_schema_2.json +10 -0
- data/test/schemas/good_schema_extends1.json +10 -0
- data/test/schemas/good_schema_extends2.json +13 -0
- data/test/schemas/inner.schema.json +21 -0
- data/test/schemas/one_of_ref_links_schema.json +16 -0
- data/test/schemas/self_link_schema.json +17 -0
- data/test/schemas/up_link_schema.json +17 -0
- data/test/test_all_of_ref_schema.rb +11 -0
- data/test/test_any_of_ref_schema.rb +11 -0
- data/test/test_bad_schema_ref.rb +33 -0
- data/test/test_extended_schema.rb +68 -0
- data/test/test_extends_and_additionalProperties.rb +50 -0
- data/test/test_files_v3.rb +52 -0
- data/test/test_fragment_resolution.rb +31 -0
- data/test/test_full_validation.rb +209 -0
- data/test/test_jsonschema_draft1.rb +701 -0
- data/test/test_jsonschema_draft2.rb +773 -0
- data/test/test_jsonschema_draft3.rb +1236 -0
- data/test/test_jsonschema_draft4.rb +1356 -0
- data/test/test_model_validator.rb +52 -0
- data/test/test_one_of.rb +42 -0
- data/test/test_ruby_schema.rb +38 -0
- data/test/test_schema_type_attribute.rb +21 -0
- data/test/test_schema_validation.rb +85 -0
- metadata +180 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
module JSON
|
2
|
+
class Schema
|
3
|
+
class AllOfAttribute < Attribute
|
4
|
+
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
5
|
+
# Create an array to hold errors that are generated during validation
|
6
|
+
errors = []
|
7
|
+
valid = true
|
8
|
+
|
9
|
+
current_schema.schema['allOf'].each do |element|
|
10
|
+
schema = JSON::Schema.new(element,current_schema.uri,validator)
|
11
|
+
|
12
|
+
# We're going to add a little cruft here to try and maintain any validation errors that occur in the allOf
|
13
|
+
# We'll handle this by keeping an error count before and after validation, extracting those errors and pushing them onto an error array
|
14
|
+
pre_validation_error_count = validation_errors(processor).count
|
15
|
+
|
16
|
+
begin
|
17
|
+
schema.validate(data,fragments,processor,options)
|
18
|
+
rescue ValidationError
|
19
|
+
valid = false
|
20
|
+
end
|
21
|
+
|
22
|
+
diff = validation_errors(processor).count - pre_validation_error_count
|
23
|
+
while diff > 0
|
24
|
+
diff = diff - 1
|
25
|
+
errors.push(validation_errors(processor).pop)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
if !valid || !errors.empty?
|
30
|
+
message = "The property '#{build_fragment(fragments)}' of type #{data.class} did not match all of the required schemas"
|
31
|
+
validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :all_of })
|
32
|
+
validation_errors(processor).last.sub_errors = errors
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module JSON
|
2
|
+
class Schema
|
3
|
+
class AnyOfAttribute < Attribute
|
4
|
+
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
5
|
+
# Create an array to hold errors that are generated during validation
|
6
|
+
errors = []
|
7
|
+
valid = false
|
8
|
+
|
9
|
+
current_schema.schema['anyOf'].each do |element|
|
10
|
+
schema = JSON::Schema.new(element,current_schema.uri,validator)
|
11
|
+
|
12
|
+
# We're going to add a little cruft here to try and maintain any validation errors that occur in the anyOf
|
13
|
+
# We'll handle this by keeping an error count before and after validation, extracting those errors and pushing them onto a union error
|
14
|
+
pre_validation_error_count = validation_errors(processor).count
|
15
|
+
|
16
|
+
begin
|
17
|
+
schema.validate(data,fragments,processor,options)
|
18
|
+
valid = true
|
19
|
+
rescue ValidationError
|
20
|
+
# We don't care that these schemas don't validate - we only care that one validated
|
21
|
+
end
|
22
|
+
|
23
|
+
diff = validation_errors(processor).count - pre_validation_error_count
|
24
|
+
valid = false if diff > 0
|
25
|
+
while diff > 0
|
26
|
+
diff = diff - 1
|
27
|
+
errors.push(validation_errors(processor).pop)
|
28
|
+
end
|
29
|
+
|
30
|
+
break if valid
|
31
|
+
end
|
32
|
+
|
33
|
+
if !valid
|
34
|
+
message = "The property '#{build_fragment(fragments)}' of type #{data.class} did not match one or more of the required schemas"
|
35
|
+
validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :any_of })
|
36
|
+
validation_errors(processor).last.sub_errors = errors
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module JSON
|
2
|
+
class Schema
|
3
|
+
class DependenciesAttribute < Attribute
|
4
|
+
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
5
|
+
if data.is_a?(Hash)
|
6
|
+
current_schema.schema['dependencies'].each do |property,dependency_value|
|
7
|
+
if data.has_key?(property.to_s) || data.has_key?(property.to_sym)
|
8
|
+
if dependency_value.is_a?(String)
|
9
|
+
if !data.has_key?(dependency_value.to_s) && !data.has_key?(dependency_value.to_sym)
|
10
|
+
message = "The property '#{build_fragment(fragments)}' has a property '#{property}' that depends on a missing property '#{dependency_value}'"
|
11
|
+
validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :dependencies })
|
12
|
+
end
|
13
|
+
elsif dependency_value.is_a?(Array)
|
14
|
+
dependency_value.each do |value|
|
15
|
+
if !data.has_key?(value.to_s) && !data.has_key?(value.to_sym)
|
16
|
+
message = "The property '#{build_fragment(fragments)}' has a property '#{property}' that depends on a missing property '#{value}'"
|
17
|
+
validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :dependencies })
|
18
|
+
end
|
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
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module JSON
|
2
|
+
class Schema
|
3
|
+
class DependenciesV4Attribute < Attribute
|
4
|
+
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
5
|
+
if data.is_a?(Hash)
|
6
|
+
current_schema.schema['dependencies'].each do |property,dependency_value|
|
7
|
+
if (data.has_key?(property.to_s) || data.has_key?(property.to_sym)) && dependency_value.is_a?(Array)
|
8
|
+
dependency_value.each do |value|
|
9
|
+
if !data.has_key?(value.to_s) && !data.has_key?(value.to_sym)
|
10
|
+
message = "The property '#{build_fragment(fragments)}' has a property '#{property}' that depends on a missing property '#{value}'"
|
11
|
+
validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :dependencies })
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module JSON
|
2
|
+
class Schema
|
3
|
+
class DisallowAttribute < Attribute
|
4
|
+
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
5
|
+
if validator.attributes['type']
|
6
|
+
validator.attributes['type'].validate(current_schema, data, fragments, processor, validator, {:disallow => true}.merge(options))
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module JSON
|
2
|
+
class Schema
|
3
|
+
class DivisibleByAttribute < Attribute
|
4
|
+
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
5
|
+
if data.is_a?(Numeric)
|
6
|
+
if current_schema.schema['divisibleBy'] == 0 ||
|
7
|
+
current_schema.schema['divisibleBy'] == 0.0 ||
|
8
|
+
(BigDecimal.new(data.to_s) % BigDecimal.new(current_schema.schema['divisibleBy'].to_s)).to_f != 0
|
9
|
+
message = "The property '#{build_fragment(fragments)}' was not divisible by #{current_schema.schema['divisibleBy']}"
|
10
|
+
validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :divisible_by })
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module JSON
|
2
|
+
class Schema
|
3
|
+
class EnumAttribute < Attribute
|
4
|
+
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
5
|
+
if !current_schema.schema['enum'].include?(data)
|
6
|
+
message = "The property '#{build_fragment(fragments)}' value #{data.inspect} did not match one of the following values:"
|
7
|
+
current_schema.schema['enum'].each {|val|
|
8
|
+
if val.is_a?(NilClass)
|
9
|
+
message += " null,"
|
10
|
+
elsif val.is_a?(Array)
|
11
|
+
message += " (array),"
|
12
|
+
elsif val.is_a?(Hash)
|
13
|
+
message += " (object),"
|
14
|
+
else
|
15
|
+
message += " #{val.to_s},"
|
16
|
+
end
|
17
|
+
}
|
18
|
+
message.chop!
|
19
|
+
validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :enum })
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'json-schema/attributes/ref'
|
2
|
+
|
3
|
+
module JSON
|
4
|
+
class Schema
|
5
|
+
class ExtendsAttribute < Attribute
|
6
|
+
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
7
|
+
schemas = current_schema.schema['extends']
|
8
|
+
schemas = [schemas] if !schemas.is_a?(Array)
|
9
|
+
schemas.each do |s|
|
10
|
+
uri,schema = get_extended_uri_and_schema(s, current_schema, validator)
|
11
|
+
if schema
|
12
|
+
schema.validate(data, fragments, processor, options)
|
13
|
+
elsif uri
|
14
|
+
message = "The extended schema '#{uri.to_s}' cannot be found"
|
15
|
+
validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :extends })
|
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], { property: last_fragment_as_symbol(fragments), failure: :extends })
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.get_extended_uri_and_schema(s, current_schema, validator)
|
24
|
+
uri,schema = nil,nil
|
25
|
+
|
26
|
+
s = {'$ref' => s} if s.is_a?(String)
|
27
|
+
|
28
|
+
if s.is_a?(Hash)
|
29
|
+
uri = current_schema.uri
|
30
|
+
if s['$ref']
|
31
|
+
ref_uri,ref_schema = JSON::Schema::RefAttribute.get_referenced_uri_and_schema(s, current_schema, validator)
|
32
|
+
if ref_schema
|
33
|
+
if s.size == 1 # Check if anything else apart from $ref
|
34
|
+
uri,schema = ref_uri,ref_schema
|
35
|
+
else
|
36
|
+
s = s.dup
|
37
|
+
s.delete '$ref'
|
38
|
+
s = ref_schema.schema.merge(s)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
schema ||= JSON::Schema.new(s,uri,validator)
|
43
|
+
end
|
44
|
+
|
45
|
+
[uri,schema]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module JSON
|
4
|
+
class Schema
|
5
|
+
class FormatAttribute < Attribute
|
6
|
+
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
7
|
+
case current_schema.schema['format']
|
8
|
+
|
9
|
+
# Timestamp in restricted ISO-8601 YYYY-MM-DDThh:mm:ssZ with optional decimal fraction of the second
|
10
|
+
when 'date-time'
|
11
|
+
if data.is_a?(String)
|
12
|
+
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"
|
13
|
+
r = Regexp.new('^\d\d\d\d-\d\d-\d\dT(\d\d):(\d\d):(\d\d)([\.,]\d+)?(Z|[+-](\d\d)(:?\d\d)?)?$')
|
14
|
+
if (m = r.match(data))
|
15
|
+
parts = data.split("T")
|
16
|
+
begin
|
17
|
+
Date.parse(parts[0])
|
18
|
+
rescue Exception
|
19
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :format })
|
20
|
+
return
|
21
|
+
end
|
22
|
+
begin
|
23
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :format }) and return if m[1].to_i > 23
|
24
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :format }) and return if m[2].to_i > 59
|
25
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :format }) and return if m[3].to_i > 59
|
26
|
+
rescue Exception
|
27
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :format })
|
28
|
+
return
|
29
|
+
end
|
30
|
+
else
|
31
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :format })
|
32
|
+
return
|
33
|
+
end
|
34
|
+
end
|
35
|
+
# Date in the format of YYYY-MM-DD
|
36
|
+
when 'date'
|
37
|
+
if data.is_a?(String)
|
38
|
+
error_message = "The property '#{build_fragment(fragments)}' must be a date in the format of YYYY-MM-DD"
|
39
|
+
r = Regexp.new('^\d\d\d\d-\d\d-\d\d$')
|
40
|
+
if (m = r.match(data))
|
41
|
+
begin
|
42
|
+
Date.parse(data)
|
43
|
+
rescue Exception
|
44
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :format })
|
45
|
+
return
|
46
|
+
end
|
47
|
+
else
|
48
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :format })
|
49
|
+
return
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Time in the format of HH:MM:SS
|
54
|
+
when 'time'
|
55
|
+
if data.is_a?(String)
|
56
|
+
error_message = "The property '#{build_fragment(fragments)}' must be a time in the format of hh:mm:ss"
|
57
|
+
r = Regexp.new('^(\d\d):(\d\d):(\d\d)$')
|
58
|
+
if (m = r.match(data))
|
59
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :format }) and return if m[1].to_i > 23
|
60
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :format }) and return if m[2].to_i > 59
|
61
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :format }) and return if m[3].to_i > 59
|
62
|
+
else
|
63
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :format })
|
64
|
+
return
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# IPv4 in dotted-quad format
|
69
|
+
when 'ip-address', 'ipv4'
|
70
|
+
if data.is_a?(String)
|
71
|
+
error_message = "The property '#{build_fragment(fragments)}' must be a valid IPv4 address"
|
72
|
+
r = Regexp.new('^(\d+){1,3}\.(\d+){1,3}\.(\d+){1,3}\.(\d+){1,3}$')
|
73
|
+
if (m = r.match(data))
|
74
|
+
1.upto(4) do |x|
|
75
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :format }) and return if m[x].to_i > 255
|
76
|
+
end
|
77
|
+
else
|
78
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :format })
|
79
|
+
return
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# IPv6 in standard format (including abbreviations)
|
84
|
+
when 'ipv6'
|
85
|
+
if data.is_a?(String)
|
86
|
+
error_message = "The property '#{build_fragment(fragments)}' must be a valid IPv6 address"
|
87
|
+
r = Regexp.new('^[a-f0-9:]+$')
|
88
|
+
if (m = r.match(data))
|
89
|
+
# All characters are valid, now validate structure
|
90
|
+
parts = data.split(":")
|
91
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :format }) and return if parts.length > 8
|
92
|
+
condensed_zeros = false
|
93
|
+
parts.each do |part|
|
94
|
+
if part.length == 0
|
95
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :format }) and return if condensed_zeros
|
96
|
+
condensed_zeros = true
|
97
|
+
end
|
98
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :format }) and return if part.length > 4
|
99
|
+
end
|
100
|
+
else
|
101
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :format })
|
102
|
+
return
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
when 'uri'
|
107
|
+
if data.is_a?(String)
|
108
|
+
error_message = "The property '#{build_fragment(fragments)}' must be a valid URI"
|
109
|
+
begin
|
110
|
+
URI.parse(data)
|
111
|
+
rescue URI::InvalidURIError
|
112
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :format })
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
when 'hostname'
|
117
|
+
|
118
|
+
when 'email'
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module JSON
|
2
|
+
class Schema
|
3
|
+
class ItemsAttribute < Attribute
|
4
|
+
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
5
|
+
if data.is_a?(Array)
|
6
|
+
if current_schema.schema['items'].is_a?(Hash)
|
7
|
+
data.each_with_index do |item,i|
|
8
|
+
schema = JSON::Schema.new(current_schema.schema['items'],current_schema.uri,validator)
|
9
|
+
fragments << i.to_s
|
10
|
+
schema.validate(item,fragments, processor, options)
|
11
|
+
fragments.pop
|
12
|
+
end
|
13
|
+
elsif current_schema.schema['items'].is_a?(Array)
|
14
|
+
current_schema.schema['items'].each_with_index do |item_schema,i|
|
15
|
+
schema = JSON::Schema.new(item_schema,current_schema.uri,validator)
|
16
|
+
fragments << i.to_s
|
17
|
+
schema.validate(data[i],fragments, processor, options)
|
18
|
+
fragments.pop
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module JSON
|
2
|
+
class Schema
|
3
|
+
class MaxDecimalAttribute < Attribute
|
4
|
+
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
5
|
+
if data.is_a?(Numeric)
|
6
|
+
s = data.to_s.split(".")[1]
|
7
|
+
if s && s.length > current_schema.schema['maxDecimal']
|
8
|
+
message = "The property '#{build_fragment(fragments)}' had more decimal places than the allowed #{current_schema.schema['maxDecimal']}"
|
9
|
+
validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :max_decimal })
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module JSON
|
2
|
+
class Schema
|
3
|
+
class MaximumAttribute < Attribute
|
4
|
+
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
5
|
+
if data.is_a?(Numeric)
|
6
|
+
if (current_schema.schema['exclusiveMaximum'] ? data >= current_schema.schema['maximum'] : data > current_schema.schema['maximum'])
|
7
|
+
message = "The property '#{build_fragment(fragments)}' did not have a maximum value of #{current_schema.schema['maximum']}, "
|
8
|
+
message += current_schema.schema['exclusiveMaximum'] ? 'exclusively' : 'inclusively'
|
9
|
+
validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :maximum })
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module JSON
|
2
|
+
class Schema
|
3
|
+
class MaximumInclusiveAttribute < Attribute
|
4
|
+
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
5
|
+
if data.is_a?(Numeric)
|
6
|
+
if (current_schema.schema['maximumCanEqual'] == false ? data >= current_schema.schema['maximum'] : data > current_schema.schema['maximum'])
|
7
|
+
message = "The property '#{build_fragment(fragments)}' did not have a maximum value of #{current_schema.schema['maximum']}, "
|
8
|
+
message += current_schema.schema['exclusiveMaximum'] ? 'exclusively' : 'inclusively'
|
9
|
+
validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :maximum_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 MaxItemsAttribute < Attribute
|
4
|
+
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
5
|
+
if data.is_a?(Array) && (data.compact.size > current_schema.schema['maxItems'])
|
6
|
+
message = "The property '#{build_fragment(fragments)}' had more items than the allowed #{current_schema.schema['maxItems']}"
|
7
|
+
validation_error(processor, message, fragments, current_schema, self, options[:record_errors], { property: last_fragment_as_symbol(fragments), failure: :max_items })
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|