json-schema-openc-fork 0.0.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 +15 -0
- data/LICENSE.md +19 -0
- data/README.textile +452 -0
- data/lib/json-schema.rb +19 -0
- data/lib/json-schema/attribute.rb +43 -0
- data/lib/json-schema/attributes/additionalitems.rb +28 -0
- data/lib/json-schema/attributes/additionalproperties.rb +58 -0
- data/lib/json-schema/attributes/allof.rb +39 -0
- data/lib/json-schema/attributes/anyof.rb +47 -0
- data/lib/json-schema/attributes/dependencies.rb +44 -0
- data/lib/json-schema/attributes/disallow.rb +12 -0
- data/lib/json-schema/attributes/divisibleby.rb +22 -0
- data/lib/json-schema/attributes/enum.rb +24 -0
- data/lib/json-schema/attributes/extends.rb +50 -0
- data/lib/json-schema/attributes/format.rb +14 -0
- data/lib/json-schema/attributes/formats/custom.rb +21 -0
- data/lib/json-schema/attributes/formats/date.rb +24 -0
- data/lib/json-schema/attributes/formats/date_time.rb +36 -0
- data/lib/json-schema/attributes/formats/date_time_v4.rb +15 -0
- data/lib/json-schema/attributes/formats/ip.rb +41 -0
- data/lib/json-schema/attributes/formats/time.rb +22 -0
- data/lib/json-schema/attributes/formats/uri.rb +20 -0
- data/lib/json-schema/attributes/items.rb +26 -0
- data/lib/json-schema/attributes/limit.rb +179 -0
- data/lib/json-schema/attributes/maxdecimal.rb +18 -0
- data/lib/json-schema/attributes/multipleof.rb +11 -0
- data/lib/json-schema/attributes/not.rb +30 -0
- data/lib/json-schema/attributes/oneof.rb +56 -0
- data/lib/json-schema/attributes/pattern.rb +18 -0
- data/lib/json-schema/attributes/patternproperties.rb +22 -0
- data/lib/json-schema/attributes/properties.rb +74 -0
- data/lib/json-schema/attributes/properties_optional.rb +26 -0
- data/lib/json-schema/attributes/ref.rb +74 -0
- data/lib/json-schema/attributes/required.rb +28 -0
- data/lib/json-schema/attributes/type.rb +83 -0
- data/lib/json-schema/attributes/type_v4.rb +29 -0
- data/lib/json-schema/attributes/uniqueitems.rb +16 -0
- 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 +63 -0
- data/lib/json-schema/schema/reader.rb +113 -0
- data/lib/json-schema/schema/validator.rb +36 -0
- data/lib/json-schema/util/array_set.rb +14 -0
- data/lib/json-schema/util/uri.rb +16 -0
- data/lib/json-schema/util/uuid.rb +285 -0
- data/lib/json-schema/validator.rb +592 -0
- data/lib/json-schema/validators/draft1.rb +45 -0
- data/lib/json-schema/validators/draft2.rb +46 -0
- data/lib/json-schema/validators/draft3.rb +50 -0
- data/lib/json-schema/validators/draft4.rb +56 -0
- data/lib/json-schema/validators/hyper-draft4.rb +14 -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/address_microformat.json +18 -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/definition_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/ref john with spaces schema.json +11 -0
- data/test/schemas/relative_definition_schema.json +8 -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 +35 -0
- data/test/test_any_of_ref_schema.rb +35 -0
- data/test/test_bad_schema_ref.rb +39 -0
- data/test/test_common_test_suite.rb +66 -0
- data/test/test_custom_format.rb +116 -0
- data/test/test_definition.rb +15 -0
- data/test/test_extended_schema.rb +62 -0
- data/test/test_extends_and_additionalProperties.rb +52 -0
- data/test/test_files_v3.rb +43 -0
- data/test/test_fragment_resolution.rb +30 -0
- data/test/test_fragment_validation_with_ref.rb +34 -0
- data/test/test_full_validation.rb +208 -0
- data/test/test_helper.rb +47 -0
- data/test/test_initialize_data.rb +118 -0
- data/test/test_jsonschema_draft1.rb +171 -0
- data/test/test_jsonschema_draft2.rb +142 -0
- data/test/test_jsonschema_draft3.rb +502 -0
- data/test/test_jsonschema_draft4.rb +704 -0
- data/test/test_list_option.rb +21 -0
- data/test/test_merge_missing_values.rb +45 -0
- data/test/test_minitems.rb +16 -0
- data/test/test_one_of.rb +85 -0
- data/test/test_ruby_schema.rb +59 -0
- data/test/test_schema_loader.rb +74 -0
- data/test/test_schema_type_attribute.rb +20 -0
- data/test/test_schema_validation.rb +185 -0
- data/test/test_stringify.rb +48 -0
- data/test/test_uri_related.rb +67 -0
- data/test/test_validator.rb +53 -0
- metadata +284 -0
data/lib/json-schema.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
if Gem::Specification::find_all_by_name('multi_json').any?
|
4
|
+
require 'multi_json'
|
5
|
+
|
6
|
+
# Force MultiJson to load an engine before we define the JSON constant here; otherwise,
|
7
|
+
# it looks for things that are under the JSON namespace that aren't there (since we have defined it here)
|
8
|
+
MultiJson.respond_to?(:adapter) ? MultiJson.adapter : MultiJson.engine
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'json-schema/util/array_set'
|
12
|
+
require 'json-schema/util/uri'
|
13
|
+
require 'json-schema/schema'
|
14
|
+
require 'json-schema/schema/reader'
|
15
|
+
require 'json-schema/validator'
|
16
|
+
|
17
|
+
Dir[File.join(File.dirname(__FILE__), "json-schema/attributes/*.rb")].each {|file| require file }
|
18
|
+
Dir[File.join(File.dirname(__FILE__), "json-schema/attributes/formats/*.rb")].each {|file| require file }
|
19
|
+
Dir[File.join(File.dirname(__FILE__), "json-schema/validators/*.rb")].sort!.each {|file| require file }
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'json-schema/errors/validation_error'
|
2
|
+
|
3
|
+
module JSON
|
4
|
+
class Schema
|
5
|
+
class Attribute
|
6
|
+
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.build_fragment(fragments)
|
10
|
+
"#/#{fragments.join('/')}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.validation_error(processor, message, fragments, current_schema, failed_attribute, record_errors)
|
14
|
+
error = ValidationError.new(message, fragments, failed_attribute, current_schema)
|
15
|
+
if record_errors
|
16
|
+
processor.validation_error(error)
|
17
|
+
else
|
18
|
+
raise error
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.validation_errors(validator)
|
23
|
+
validator.validation_errors
|
24
|
+
end
|
25
|
+
|
26
|
+
TYPE_CLASS_MAPPINGS = {
|
27
|
+
"string" => String,
|
28
|
+
"number" => Numeric,
|
29
|
+
"integer" => Integer,
|
30
|
+
"boolean" => [TrueClass, FalseClass],
|
31
|
+
"object" => Hash,
|
32
|
+
"array" => Array,
|
33
|
+
"null" => NilClass,
|
34
|
+
"any" => Object
|
35
|
+
}
|
36
|
+
|
37
|
+
def self.data_valid_for_type?(data, type)
|
38
|
+
valid_classes = TYPE_CLASS_MAPPINGS.fetch(type) { return true }
|
39
|
+
Array(valid_classes).any? { |c| data.is_a?(c) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'json-schema/attribute'
|
2
|
+
|
3
|
+
module JSON
|
4
|
+
class Schema
|
5
|
+
class AdditionalItemsAttribute < Attribute
|
6
|
+
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
7
|
+
return unless data.is_a?(Array)
|
8
|
+
|
9
|
+
schema = current_schema.schema
|
10
|
+
return unless schema['items'].is_a?(Array)
|
11
|
+
|
12
|
+
case schema['additionalItems']
|
13
|
+
when false
|
14
|
+
if schema['items'].length != data.length
|
15
|
+
message = "The property '#{build_fragment(fragments)}' contains additional array elements outside of the schema when none are allowed"
|
16
|
+
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
|
17
|
+
end
|
18
|
+
when Hash
|
19
|
+
additional_items_schema = JSON::Schema.new(schema['additionalItems'], current_schema.uri, validator)
|
20
|
+
data.each_with_index do |item, i|
|
21
|
+
next if i < schema['items'].length
|
22
|
+
additional_items_schema.validate(item, fragments + [i.to_s], processor, options)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'json-schema/attribute'
|
2
|
+
require 'json-schema/attributes/extends'
|
3
|
+
|
4
|
+
module JSON
|
5
|
+
class Schema
|
6
|
+
class AdditionalPropertiesAttribute < Attribute
|
7
|
+
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
8
|
+
schema = current_schema.schema
|
9
|
+
return unless data.is_a?(Hash) && (schema['type'].nil? || schema['type'] == 'object')
|
10
|
+
|
11
|
+
extra_properties = remove_valid_properties(data.keys, current_schema, validator)
|
12
|
+
|
13
|
+
addprop = schema['additionalProperties']
|
14
|
+
if addprop.is_a?(Hash)
|
15
|
+
matching_properties = extra_properties # & addprop.keys
|
16
|
+
matching_properties.each do |key|
|
17
|
+
additional_property_schema = JSON::Schema.new(addprop[key] || addprop, current_schema.uri, validator)
|
18
|
+
additional_property_schema.validate(data[key], fragments + [key], processor, options)
|
19
|
+
end
|
20
|
+
extra_properties -= matching_properties
|
21
|
+
end
|
22
|
+
|
23
|
+
if extra_properties.any? && (addprop == false || (addprop.is_a?(Hash) && !addprop.empty?))
|
24
|
+
message = "The property '#{build_fragment(fragments)}' contains additional properties #{extra_properties.inspect} outside of the schema when none are allowed"
|
25
|
+
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.remove_valid_properties(extra_properties, current_schema, validator)
|
30
|
+
schema = current_schema.schema
|
31
|
+
|
32
|
+
if schema['properties']
|
33
|
+
extra_properties = extra_properties - schema['properties'].keys
|
34
|
+
end
|
35
|
+
|
36
|
+
if schema['patternProperties']
|
37
|
+
schema['patternProperties'].each_key do |key|
|
38
|
+
regexp = Regexp.new(key)
|
39
|
+
extra_properties.reject! { |prop| regexp.match(prop) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
if extended_schemas = schema['extends']
|
44
|
+
extended_schemas = [extended_schemas] unless extended_schemas.is_a?(Array)
|
45
|
+
extended_schemas.each do |schema_value|
|
46
|
+
_, extended_schema = JSON::Schema::ExtendsAttribute.get_extended_uri_and_schema(schema_value, current_schema, validator)
|
47
|
+
if extended_schema
|
48
|
+
extra_properties = remove_valid_properties(extra_properties, extended_schema, validator)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
extra_properties
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -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 #{data.class} 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 #{data.class} 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,44 @@
|
|
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
|
+
|
38
|
+
class DependenciesV4Attribute < DependenciesAttribute
|
39
|
+
def self.accept_value?(value)
|
40
|
+
value.is_a?(Array) || value.is_a?(Hash)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
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.new(data.to_s) % BigDecimal.new(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,50 @@
|
|
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
|
+
s = {'$ref' => s} if s.is_a?(String)
|
28
|
+
|
29
|
+
if s.is_a?(Hash)
|
30
|
+
uri = current_schema.uri
|
31
|
+
if s['$ref']
|
32
|
+
ref_uri,ref_schema = JSON::Schema::RefAttribute.get_referenced_uri_and_schema(s, current_schema, validator)
|
33
|
+
if ref_schema
|
34
|
+
if s.size == 1 # Check if anything else apart from $ref
|
35
|
+
uri,schema = ref_uri,ref_schema
|
36
|
+
else
|
37
|
+
s = s.dup
|
38
|
+
s.delete '$ref'
|
39
|
+
s = ref_schema.schema.merge(s)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
schema ||= JSON::Schema.new(s,uri,validator)
|
44
|
+
end
|
45
|
+
|
46
|
+
[uri,schema]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
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/attribute'
|
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,24 @@
|
|
1
|
+
require 'json-schema/attribute'
|
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 Exception
|
15
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
|
16
|
+
end
|
17
|
+
else
|
18
|
+
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|