json-schema 2.2.5 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/README.textile +1 -1
- data/lib/json-schema.rb +1 -0
- data/lib/json-schema/attribute.rb +43 -0
- data/lib/json-schema/attributes/additionalitems.rb +3 -1
- data/lib/json-schema/attributes/additionalproperties.rb +1 -0
- data/lib/json-schema/attributes/allof.rb +6 -4
- data/lib/json-schema/attributes/anyof.rb +7 -5
- data/lib/json-schema/attributes/dependencies.rb +3 -1
- data/lib/json-schema/attributes/dependencies_v4.rb +3 -1
- data/lib/json-schema/attributes/disallow.rb +3 -1
- data/lib/json-schema/attributes/divisibleby.rb +3 -1
- data/lib/json-schema/attributes/enum.rb +3 -1
- data/lib/json-schema/attributes/extends.rb +1 -0
- data/lib/json-schema/attributes/format.rb +6 -112
- data/lib/json-schema/attributes/formats/custom.rb +22 -0
- data/lib/json-schema/attributes/formats/date.rb +25 -0
- data/lib/json-schema/attributes/formats/date_time.rb +35 -0
- data/lib/json-schema/attributes/formats/ip4.rb +22 -0
- data/lib/json-schema/attributes/formats/ip6.rb +30 -0
- data/lib/json-schema/attributes/formats/time.rb +22 -0
- data/lib/json-schema/attributes/formats/uri.rb +18 -0
- data/lib/json-schema/attributes/items.rb +3 -1
- data/lib/json-schema/attributes/maxdecimal.rb +3 -1
- data/lib/json-schema/attributes/maximum.rb +3 -1
- data/lib/json-schema/attributes/maximum_inclusive.rb +2 -0
- data/lib/json-schema/attributes/maxitems.rb +2 -0
- data/lib/json-schema/attributes/maxlength.rb +3 -1
- data/lib/json-schema/attributes/maxproperties.rb +3 -1
- data/lib/json-schema/attributes/minimum.rb +3 -1
- data/lib/json-schema/attributes/minimum_inclusive.rb +3 -1
- data/lib/json-schema/attributes/minitems.rb +4 -2
- data/lib/json-schema/attributes/minlength.rb +3 -1
- data/lib/json-schema/attributes/minproperties.rb +3 -1
- data/lib/json-schema/attributes/multipleof.rb +3 -1
- data/lib/json-schema/attributes/not.rb +3 -1
- data/lib/json-schema/attributes/oneof.rb +2 -0
- data/lib/json-schema/attributes/pattern.rb +3 -1
- data/lib/json-schema/attributes/patternproperties.rb +3 -1
- data/lib/json-schema/attributes/properties.rb +4 -2
- data/lib/json-schema/attributes/properties_optional.rb +3 -1
- data/lib/json-schema/attributes/properties_v4.rb +2 -0
- data/lib/json-schema/attributes/ref.rb +3 -0
- data/lib/json-schema/attributes/required.rb +2 -0
- data/lib/json-schema/attributes/type.rb +6 -20
- data/lib/json-schema/attributes/type_v4.rb +3 -21
- data/lib/json-schema/attributes/uniqueitems.rb +3 -1
- data/lib/json-schema/errors/custom_format_error.rb +6 -0
- data/lib/json-schema/errors/json_parse_error.rb +6 -0
- data/lib/json-schema/errors/schema_error.rb +6 -0
- data/lib/json-schema/errors/validation_error.rb +46 -0
- data/lib/json-schema/schema.rb +1 -5
- data/lib/json-schema/schema/validator.rb +31 -0
- data/lib/json-schema/validator.rb +61 -126
- data/lib/json-schema/validators/draft1.rb +14 -1
- data/lib/json-schema/validators/draft2.rb +14 -1
- data/lib/json-schema/validators/draft3.rb +14 -2
- data/lib/json-schema/validators/draft4.rb +12 -1
- data/test/test_all_of_ref_schema.rb +29 -2
- data/test/test_any_of_ref_schema.rb +26 -0
- data/test/test_bad_schema_ref.rb +2 -2
- data/test/test_common_test_suite.rb +53 -0
- data/test/test_custom_format.rb +117 -0
- data/test/test_jsonschema_draft1.rb +12 -0
- data/test/test_jsonschema_draft2.rb +12 -0
- data/test/test_jsonschema_draft3.rb +31 -0
- data/test/test_jsonschema_draft4.rb +14 -48
- data/test/test_minitems.rb +18 -0
- metadata +21 -4
- data/test/test_suite.rb +0 -71
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'json-schema/attribute'
|
2
|
+
require 'uri'
|
3
|
+
module JSON
|
4
|
+
class Schema
|
5
|
+
class IP4Format < FormatAttribute
|
6
|
+
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
7
|
+
if data.is_a?(String)
|
8
|
+
error_message = "The property '#{build_fragment(fragments)}' must be a valid IPv4 address"
|
9
|
+
r = Regexp.new('^(\d+){1,3}\.(\d+){1,3}\.(\d+){1,3}\.(\d+){1,3}$')
|
10
|
+
if (m = r.match(data))
|
11
|
+
1.upto(4) do |x|
|
12
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if m[x].to_i > 255
|
13
|
+
end
|
14
|
+
else
|
15
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
|
16
|
+
return
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'json-schema/attribute'
|
2
|
+
require 'uri'
|
3
|
+
module JSON
|
4
|
+
class Schema
|
5
|
+
class IP6Format < FormatAttribute
|
6
|
+
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
7
|
+
if data.is_a?(String)
|
8
|
+
error_message = "The property '#{build_fragment(fragments)}' must be a valid IPv6 address"
|
9
|
+
r = Regexp.new('^[a-f0-9:]+$')
|
10
|
+
if (r.match(data))
|
11
|
+
# All characters are valid, now validate structure
|
12
|
+
parts = data.split(":")
|
13
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if parts.length > 8
|
14
|
+
condensed_zeros = false
|
15
|
+
parts.each do |part|
|
16
|
+
if part.length == 0
|
17
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if condensed_zeros
|
18
|
+
condensed_zeros = true
|
19
|
+
end
|
20
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if part.length > 4
|
21
|
+
end
|
22
|
+
else
|
23
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
|
24
|
+
return
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'json-schema/attribute'
|
2
|
+
require 'uri'
|
3
|
+
module JSON
|
4
|
+
class Schema
|
5
|
+
class TimeFormat < FormatAttribute
|
6
|
+
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
7
|
+
if data.is_a?(String)
|
8
|
+
error_message = "The property '#{build_fragment(fragments)}' must be a time in the format of hh:mm:ss"
|
9
|
+
r = Regexp.new('^(\d\d):(\d\d):(\d\d)$')
|
10
|
+
if (m = r.match(data))
|
11
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if m[1].to_i > 23
|
12
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if m[2].to_i > 59
|
13
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if m[3].to_i > 59
|
14
|
+
else
|
15
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
|
16
|
+
return
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'json-schema/attribute'
|
2
|
+
require 'uri'
|
3
|
+
module JSON
|
4
|
+
class Schema
|
5
|
+
class UriFormat < FormatAttribute
|
6
|
+
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
7
|
+
if data.is_a?(String)
|
8
|
+
error_message = "The property '#{build_fragment(fragments)}' must be a valid URI"
|
9
|
+
begin
|
10
|
+
URI.parse(URI.escape(data))
|
11
|
+
rescue URI::InvalidURIError
|
12
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,12 +1,14 @@
|
|
1
|
+
require 'json-schema/attribute'
|
2
|
+
|
1
3
|
module JSON
|
2
4
|
class Schema
|
3
5
|
class MinItemsAttribute < Attribute
|
4
6
|
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
5
|
-
if data.is_a?(Array) && (data.
|
7
|
+
if data.is_a?(Array) && (data.size < current_schema.schema['minItems'])
|
6
8
|
message = "The property '#{build_fragment(fragments)}' did not contain a minimum number of items #{current_schema.schema['minItems']}"
|
7
9
|
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
|
8
10
|
end
|
9
11
|
end
|
10
12
|
end
|
11
13
|
end
|
12
|
-
end
|
14
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'json-schema/attribute'
|
2
|
+
|
1
3
|
module JSON
|
2
4
|
class Schema
|
3
5
|
class PropertiesAttribute < Attribute
|
@@ -13,8 +15,8 @@ module JSON
|
|
13
15
|
data[property.to_s] = (default.is_a?(Hash) ? default.clone : default)
|
14
16
|
end
|
15
17
|
|
16
|
-
|
17
|
-
|
18
|
+
if property_schema.fetch('required') { options[:strict] } &&
|
19
|
+
!data.has_key?(property.to_s) && !data.has_key?(property.to_sym)
|
18
20
|
message = "The property '#{build_fragment(fragments)}' did not contain a required property of '#{property}'"
|
19
21
|
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
|
20
22
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'json-schema/attribute'
|
2
|
+
|
1
3
|
module JSON
|
2
4
|
class Schema
|
3
5
|
class TypeAttribute < Attribute
|
@@ -15,10 +17,10 @@ module JSON
|
|
15
17
|
end
|
16
18
|
valid = false
|
17
19
|
|
18
|
-
# Create
|
19
|
-
union_errors = []
|
20
|
+
# Create a hash to hold errors that are generated during union validation
|
21
|
+
union_errors = Hash.new { |hsh, k| hsh[k] = [] }
|
20
22
|
|
21
|
-
types.
|
23
|
+
types.each_with_index do |type, type_index|
|
22
24
|
if type.is_a?(String)
|
23
25
|
valid = data_valid_for_type?(data, type)
|
24
26
|
elsif type.is_a?(Hash) && union
|
@@ -40,7 +42,7 @@ module JSON
|
|
40
42
|
valid = false if diff > 0
|
41
43
|
while diff > 0
|
42
44
|
diff = diff - 1
|
43
|
-
union_errors.push(validation_errors(processor).pop)
|
45
|
+
union_errors["type ##{type_index}"].push(validation_errors(processor).pop)
|
44
46
|
end
|
45
47
|
end
|
46
48
|
|
@@ -70,22 +72,6 @@ module JSON
|
|
70
72
|
end
|
71
73
|
end
|
72
74
|
|
73
|
-
TYPE_CLASS_MAPPINGS = {
|
74
|
-
"string" => String,
|
75
|
-
"number" => Numeric,
|
76
|
-
"integer" => Integer,
|
77
|
-
"boolean" => [TrueClass, FalseClass],
|
78
|
-
"object" => Hash,
|
79
|
-
"array" => Array,
|
80
|
-
"null" => NilClass,
|
81
|
-
"any" => Object
|
82
|
-
}
|
83
|
-
|
84
|
-
def self.data_valid_for_type?(data, type)
|
85
|
-
valid_classes = TYPE_CLASS_MAPPINGS.fetch(type) { return true }
|
86
|
-
Array(valid_classes).any? { |c| data.is_a?(c) }
|
87
|
-
end
|
88
|
-
|
89
75
|
# Lookup Schema type of given class instance
|
90
76
|
def self.type_of_data(data)
|
91
77
|
type, klass = TYPE_CLASS_MAPPINGS.map { |k,v| [k,v] }.sort_by { |i|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'json-schema/attribute'
|
2
|
+
|
1
3
|
module JSON
|
2
4
|
class Schema
|
3
5
|
class TypeV4Attribute < Attribute
|
@@ -10,9 +12,6 @@ module JSON
|
|
10
12
|
end
|
11
13
|
valid = false
|
12
14
|
|
13
|
-
# Create an array to hold errors that are generated during union validation
|
14
|
-
union_errors = []
|
15
|
-
|
16
15
|
types.each do |type|
|
17
16
|
valid = data_valid_for_type?(data, type)
|
18
17
|
break if valid
|
@@ -24,7 +23,6 @@ module JSON
|
|
24
23
|
types.each {|type| message += type.is_a?(String) ? " #{type}," : " (schema)," }
|
25
24
|
message.chop!
|
26
25
|
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
|
27
|
-
validation_errors(processor).last.sub_errors = union_errors
|
28
26
|
else
|
29
27
|
message = "The property '#{build_fragment(fragments)}' of type #{data.class} did not match the following type:"
|
30
28
|
types.each {|type| message += type.is_a?(String) ? " #{type}," : " (schema)," }
|
@@ -33,22 +31,6 @@ module JSON
|
|
33
31
|
end
|
34
32
|
end
|
35
33
|
end
|
36
|
-
|
37
|
-
TYPE_CLASS_MAPPINGS = {
|
38
|
-
"string" => String,
|
39
|
-
"number" => Numeric,
|
40
|
-
"integer" => Integer,
|
41
|
-
"boolean" => [TrueClass, FalseClass],
|
42
|
-
"object" => Hash,
|
43
|
-
"array" => Array,
|
44
|
-
"null" => NilClass,
|
45
|
-
"any" => Object
|
46
|
-
}
|
47
|
-
|
48
|
-
def self.data_valid_for_type?(data, type)
|
49
|
-
valid_classes = TYPE_CLASS_MAPPINGS.fetch(type) { return true }
|
50
|
-
Array(valid_classes).any? { |c| data.is_a?(c) }
|
51
|
-
end
|
52
34
|
end
|
53
35
|
end
|
54
|
-
end
|
36
|
+
end
|