jsi 0.4.0 → 0.6.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/.yardopts +1 -1
- data/CHANGELOG.md +15 -0
- data/README.md +105 -38
- data/lib/jsi/base.rb +349 -155
- data/lib/jsi/jsi_coder.rb +5 -4
- data/lib/jsi/metaschema_node/bootstrap_schema.rb +100 -0
- data/lib/jsi/metaschema_node.rb +156 -129
- data/lib/jsi/pathed_node.rb +47 -49
- data/lib/jsi/ptr.rb +292 -0
- data/lib/jsi/schema/application/child_application/contains.rb +16 -0
- data/lib/jsi/schema/application/child_application/draft04.rb +22 -0
- data/lib/jsi/schema/application/child_application/draft06.rb +29 -0
- data/lib/jsi/schema/application/child_application/draft07.rb +29 -0
- data/lib/jsi/schema/application/child_application/items.rb +18 -0
- data/lib/jsi/schema/application/child_application/properties.rb +25 -0
- data/lib/jsi/schema/application/child_application.rb +40 -0
- data/lib/jsi/schema/application/draft04.rb +8 -0
- data/lib/jsi/schema/application/draft06.rb +8 -0
- data/lib/jsi/schema/application/draft07.rb +8 -0
- data/lib/jsi/schema/application/inplace_application/dependencies.rb +28 -0
- data/lib/jsi/schema/application/inplace_application/draft04.rb +26 -0
- data/lib/jsi/schema/application/inplace_application/draft06.rb +27 -0
- data/lib/jsi/schema/application/inplace_application/draft07.rb +33 -0
- data/lib/jsi/schema/application/inplace_application/ifthenelse.rb +20 -0
- data/lib/jsi/schema/application/inplace_application/ref.rb +18 -0
- data/lib/jsi/schema/application/inplace_application/someof.rb +29 -0
- data/lib/jsi/schema/application/inplace_application.rb +46 -0
- data/lib/jsi/schema/application.rb +12 -0
- data/lib/jsi/schema/draft04.rb +14 -0
- data/lib/jsi/schema/draft06.rb +14 -0
- data/lib/jsi/schema/draft07.rb +14 -0
- data/lib/jsi/schema/issue.rb +36 -0
- data/lib/jsi/schema/ref.rb +159 -0
- data/lib/jsi/schema/schema_ancestor_node.rb +119 -0
- data/lib/jsi/schema/validation/array.rb +69 -0
- data/lib/jsi/schema/validation/const.rb +20 -0
- data/lib/jsi/schema/validation/contains.rb +25 -0
- data/lib/jsi/schema/validation/core.rb +39 -0
- data/lib/jsi/schema/validation/dependencies.rb +49 -0
- data/lib/jsi/schema/validation/draft04/minmax.rb +91 -0
- data/lib/jsi/schema/validation/draft04.rb +112 -0
- data/lib/jsi/schema/validation/draft06.rb +122 -0
- data/lib/jsi/schema/validation/draft07.rb +159 -0
- data/lib/jsi/schema/validation/enum.rb +25 -0
- data/lib/jsi/schema/validation/ifthenelse.rb +46 -0
- data/lib/jsi/schema/validation/items.rb +54 -0
- data/lib/jsi/schema/validation/not.rb +20 -0
- data/lib/jsi/schema/validation/numeric.rb +121 -0
- data/lib/jsi/schema/validation/object.rb +45 -0
- data/lib/jsi/schema/validation/pattern.rb +34 -0
- data/lib/jsi/schema/validation/properties.rb +101 -0
- data/lib/jsi/schema/validation/property_names.rb +32 -0
- data/lib/jsi/schema/validation/ref.rb +40 -0
- data/lib/jsi/schema/validation/required.rb +27 -0
- data/lib/jsi/schema/validation/someof.rb +90 -0
- data/lib/jsi/schema/validation/string.rb +47 -0
- data/lib/jsi/schema/validation/type.rb +49 -0
- data/lib/jsi/schema/validation.rb +51 -0
- data/lib/jsi/schema.rb +486 -133
- data/lib/jsi/schema_classes.rb +157 -42
- data/lib/jsi/schema_registry.rb +141 -0
- data/lib/jsi/schema_set.rb +141 -0
- data/lib/jsi/simple_wrap.rb +2 -2
- data/lib/jsi/typelike_modules.rb +52 -37
- data/lib/jsi/util/attr_struct.rb +106 -0
- data/lib/jsi/util.rb +141 -25
- data/lib/jsi/validation/error.rb +34 -0
- data/lib/jsi/validation/result.rb +210 -0
- data/lib/jsi/validation.rb +15 -0
- data/lib/jsi/version.rb +3 -1
- data/lib/jsi.rb +55 -9
- data/lib/schemas/json-schema.org/draft-04/schema.rb +8 -3
- data/lib/schemas/json-schema.org/draft-06/schema.rb +8 -3
- data/lib/schemas/json-schema.org/draft-07/schema.rb +12 -0
- data/readme.rb +138 -0
- data/{resources}/schemas/json-schema.org/draft-04/schema.json +149 -0
- data/{resources}/schemas/json-schema.org/draft-06/schema.json +154 -0
- data/{resources}/schemas/json-schema.org/draft-07/schema.json +168 -0
- metadata +69 -118
- data/.simplecov +0 -3
- data/Rakefile.rb +0 -9
- data/jsi.gemspec +0 -28
- data/lib/jsi/base/to_rb.rb +0 -128
- data/lib/jsi/json/node.rb +0 -203
- data/lib/jsi/json/pointer.rb +0 -419
- data/lib/jsi/json-schema-fragments.rb +0 -61
- data/lib/jsi/json.rb +0 -10
- data/resources/icons/AGPL-3.0.png +0 -0
- data/test/base_array_test.rb +0 -323
- data/test/base_hash_test.rb +0 -337
- data/test/base_test.rb +0 -486
- data/test/jsi_coder_test.rb +0 -85
- data/test/jsi_json_arraynode_test.rb +0 -150
- data/test/jsi_json_hashnode_test.rb +0 -132
- data/test/jsi_json_node_test.rb +0 -257
- data/test/jsi_json_pointer_test.rb +0 -102
- data/test/jsi_test.rb +0 -11
- data/test/jsi_typelike_as_json_test.rb +0 -53
- data/test/metaschema_node_test.rb +0 -19
- data/test/schema_module_test.rb +0 -21
- data/test/schema_test.rb +0 -208
- data/test/spreedly_openapi_test.rb +0 -8
- data/test/test_helper.rb +0 -97
- data/test/util_test.rb +0 -62
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JSI
|
|
4
|
+
module Schema::Validation::Const
|
|
5
|
+
# @private
|
|
6
|
+
def internal_validate_const(result_builder)
|
|
7
|
+
if schema_content.key?('const')
|
|
8
|
+
value = schema_content['const']
|
|
9
|
+
# The value of this keyword MAY be of any type, including null.
|
|
10
|
+
# An instance validates successfully against this keyword if its value is equal to the value of
|
|
11
|
+
# the keyword.
|
|
12
|
+
result_builder.validate(
|
|
13
|
+
result_builder.instance == value,
|
|
14
|
+
'instance is not equal to `const` value',
|
|
15
|
+
keyword: 'const',
|
|
16
|
+
)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JSI
|
|
4
|
+
module Schema::Validation::Contains
|
|
5
|
+
# @private
|
|
6
|
+
def internal_validate_contains(result_builder)
|
|
7
|
+
if schema_content.key?('contains')
|
|
8
|
+
# An array instance is valid against "contains" if at least one of its elements is valid against
|
|
9
|
+
# the given schema.
|
|
10
|
+
if result_builder.instance.respond_to?(:to_ary)
|
|
11
|
+
results = {}
|
|
12
|
+
result_builder.instance.each_index do |i|
|
|
13
|
+
results[i] = result_builder.child_subschema_validate(['contains'], [i])
|
|
14
|
+
end
|
|
15
|
+
result_builder.validate(
|
|
16
|
+
results.values.any?(&:valid?),
|
|
17
|
+
'instance array does not contain any items valid against `contains` schema value',
|
|
18
|
+
keyword: 'contains',
|
|
19
|
+
results: results.values,
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JSI
|
|
4
|
+
module Schema::Validation::Core
|
|
5
|
+
# validates the given instance against this schema
|
|
6
|
+
#
|
|
7
|
+
# @private
|
|
8
|
+
# @param instance_ptr [JSI::Ptr] a pointer to the instance to validate against the schema, in the instance_document
|
|
9
|
+
# @param instance_document [#to_hash, #to_ary, Object] document containing the instance instance_ptr pointer points to
|
|
10
|
+
# @param validate_only [Boolean] whether to return a full schema validation result or a simple, validation-only result
|
|
11
|
+
# @param visited_refs [Enumerable<JSI::Schema::Ref>]
|
|
12
|
+
# @return [JSI::Validation::Result]
|
|
13
|
+
def internal_validate_instance(instance_ptr, instance_document, validate_only: false, visited_refs: [])
|
|
14
|
+
if validate_only
|
|
15
|
+
result = JSI::Validation::VALID
|
|
16
|
+
else
|
|
17
|
+
result = JSI::Validation::FullResult.new
|
|
18
|
+
end
|
|
19
|
+
result_builder = result.builder(self, instance_ptr, instance_document, validate_only, visited_refs)
|
|
20
|
+
|
|
21
|
+
catch(:jsi_validation_result) do
|
|
22
|
+
# note: true/false are not valid as schemas in draft 4; they are only values of
|
|
23
|
+
# additionalProperties / additionalItems. since their behavior is undefined, though,
|
|
24
|
+
# it's fine for them to behave the same as boolean schemas in later drafts.
|
|
25
|
+
# I don't care about draft 4 to implement a different structuring for that.
|
|
26
|
+
if schema_content == true
|
|
27
|
+
# noop
|
|
28
|
+
elsif schema_content == false
|
|
29
|
+
result_builder.validate(false, 'instance is not valid against `false` schema')
|
|
30
|
+
elsif schema_content.respond_to?(:to_hash)
|
|
31
|
+
internal_validate_keywords(result_builder)
|
|
32
|
+
else
|
|
33
|
+
result_builder.schema_error('schema is not a boolean or a JSON object')
|
|
34
|
+
end
|
|
35
|
+
result
|
|
36
|
+
end.freeze
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JSI
|
|
4
|
+
module Schema::Validation::Dependencies
|
|
5
|
+
# @private
|
|
6
|
+
def internal_validate_dependencies(result_builder)
|
|
7
|
+
if schema_content.key?('dependencies')
|
|
8
|
+
value = schema_content['dependencies']
|
|
9
|
+
# This keyword's value MUST be an object. Each property specifies a dependency. Each dependency
|
|
10
|
+
# value MUST be an array or a valid JSON Schema.
|
|
11
|
+
if value.respond_to?(:to_hash)
|
|
12
|
+
value.each_pair do |property_name, dependency|
|
|
13
|
+
if dependency.respond_to?(:to_ary)
|
|
14
|
+
# If the dependency value is an array, each element in the array, if
|
|
15
|
+
# any, MUST be a string, and MUST be unique. If the dependency key is
|
|
16
|
+
# a property in the instance, each of the items in the dependency value
|
|
17
|
+
# must be a property that exists in the instance.
|
|
18
|
+
if result_builder.instance.respond_to?(:to_hash) && result_builder.instance.key?(property_name)
|
|
19
|
+
missing_required = dependency.reject { |name| result_builder.instance.key?(name) }
|
|
20
|
+
# TODO include property_name / missing dependent required property names in the validation error
|
|
21
|
+
result_builder.validate(
|
|
22
|
+
missing_required.empty?,
|
|
23
|
+
'instance object does not contain all dependent required property names specified by `dependencies` value',
|
|
24
|
+
keyword: 'dependencies',
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
else
|
|
28
|
+
# If the dependency value is a subschema, and the dependency key is a
|
|
29
|
+
# property in the instance, the entire instance must validate against
|
|
30
|
+
# the dependency value.
|
|
31
|
+
if result_builder.instance.respond_to?(:to_hash) && result_builder.instance.key?(property_name)
|
|
32
|
+
dependency_result = result_builder.inplace_subschema_validate(['dependencies', property_name])
|
|
33
|
+
# TODO include property_name in the validation error
|
|
34
|
+
result_builder.validate(
|
|
35
|
+
dependency_result.valid?,
|
|
36
|
+
'instance object is not valid against the schema corresponding to a matched property name specified by `dependencies` value',
|
|
37
|
+
keyword: 'dependencies',
|
|
38
|
+
results: [dependency_result],
|
|
39
|
+
)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
else
|
|
44
|
+
result_builder.schema_error('`dependencies` is not an object', 'dependencies')
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JSI
|
|
4
|
+
module Schema::Validation::Draft04::MinMax
|
|
5
|
+
# @private
|
|
6
|
+
def internal_validate_maximum(result_builder)
|
|
7
|
+
if schema_content.key?('exclusiveMaximum')
|
|
8
|
+
value = schema_content['exclusiveMaximum']
|
|
9
|
+
# The value of "exclusiveMaximum" MUST be a boolean.
|
|
10
|
+
unless [true, false].include?(value)
|
|
11
|
+
result_builder.schema_error('`exclusiveMaximum` is not true or false', 'exclusiveMaximum')
|
|
12
|
+
end
|
|
13
|
+
if !schema_content.key?('maximum')
|
|
14
|
+
result_builder.schema_error('`exclusiveMaximum` has no effect without adjacent `maximum` keyword', 'exclusiveMaximum')
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
if schema_content.key?('maximum')
|
|
19
|
+
value = schema_content['maximum']
|
|
20
|
+
# The value of "maximum" MUST be a JSON number.
|
|
21
|
+
if value.is_a?(Numeric)
|
|
22
|
+
if result_builder.instance.is_a?(Numeric)
|
|
23
|
+
# Successful validation depends on the presence and value of "exclusiveMaximum":
|
|
24
|
+
if schema_content['exclusiveMaximum'] == true
|
|
25
|
+
# if "exclusiveMaximum" has boolean value true, the instance is valid if it is strictly lower
|
|
26
|
+
# than the value of "maximum".
|
|
27
|
+
result_builder.validate(
|
|
28
|
+
result_builder.instance < value,
|
|
29
|
+
'instance is not less than `maximum` value with `exclusiveMaximum` = true',
|
|
30
|
+
keyword: 'maximum',
|
|
31
|
+
)
|
|
32
|
+
else
|
|
33
|
+
# if "exclusiveMaximum" is not present, or has boolean value false, then the instance is
|
|
34
|
+
# valid if it is lower than, or equal to, the value of "maximum"
|
|
35
|
+
result_builder.validate(
|
|
36
|
+
result_builder.instance <= value,
|
|
37
|
+
'instance is not less than or equal to `maximum` value',
|
|
38
|
+
keyword: 'maximum',
|
|
39
|
+
)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
else
|
|
43
|
+
result_builder.schema_error('`maximum` is not a number', 'maximum')
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# @private
|
|
49
|
+
def internal_validate_minimum(result_builder)
|
|
50
|
+
if schema_content.key?('exclusiveMinimum')
|
|
51
|
+
value = schema_content['exclusiveMinimum']
|
|
52
|
+
# The value of "exclusiveMinimum" MUST be a boolean.
|
|
53
|
+
unless [true, false].include?(value)
|
|
54
|
+
result_builder.schema_error('`exclusiveMinimum` is not true or false', 'exclusiveMinimum')
|
|
55
|
+
end
|
|
56
|
+
if !schema_content.key?('minimum')
|
|
57
|
+
result_builder.schema_error('`exclusiveMinimum` has no effect without adjacent `minimum` keyword', 'exclusiveMinimum')
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
if schema_content.key?('minimum')
|
|
62
|
+
value = schema_content['minimum']
|
|
63
|
+
# The value of "minimum" MUST be a JSON number.
|
|
64
|
+
if value.is_a?(Numeric)
|
|
65
|
+
if result_builder.instance.is_a?(Numeric)
|
|
66
|
+
# Successful validation depends on the presence and value of "exclusiveMinimum":
|
|
67
|
+
if schema_content['exclusiveMinimum'] == true
|
|
68
|
+
# if "exclusiveMinimum" is present and has boolean value true, the instance is valid if it is
|
|
69
|
+
# strictly greater than the value of "minimum".
|
|
70
|
+
result_builder.validate(
|
|
71
|
+
result_builder.instance > value,
|
|
72
|
+
'instance is not greater than `minimum` value with `exclusiveMinimum` = true',
|
|
73
|
+
keyword: 'minimum',
|
|
74
|
+
)
|
|
75
|
+
else
|
|
76
|
+
# if "exclusiveMinimum" is not present, or has boolean value false, then the instance is
|
|
77
|
+
# valid if it is greater than, or equal to, the value of "minimum"
|
|
78
|
+
result_builder.validate(
|
|
79
|
+
result_builder.instance >= value,
|
|
80
|
+
'instance is not greater than or equal to `minimum` value',
|
|
81
|
+
keyword: 'minimum',
|
|
82
|
+
)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
else
|
|
86
|
+
result_builder.schema_error('`minimum` is not a number', 'minimum')
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JSI
|
|
4
|
+
module Schema::Validation::Draft04
|
|
5
|
+
autoload :MinMax, 'jsi/schema/validation/draft04/minmax'
|
|
6
|
+
|
|
7
|
+
include Schema::Validation::Core
|
|
8
|
+
|
|
9
|
+
include Schema::Validation::Ref
|
|
10
|
+
|
|
11
|
+
include Schema::Validation::MultipleOf
|
|
12
|
+
include Schema::Validation::Draft04::MinMax
|
|
13
|
+
|
|
14
|
+
include Schema::Validation::StringLength
|
|
15
|
+
include Schema::Validation::Pattern
|
|
16
|
+
|
|
17
|
+
include Schema::Validation::Items
|
|
18
|
+
include Schema::Validation::ArrayLength
|
|
19
|
+
include Schema::Validation::UniqueItems
|
|
20
|
+
|
|
21
|
+
include Schema::Validation::MinMaxProperties
|
|
22
|
+
include Schema::Validation::Required
|
|
23
|
+
include Schema::Validation::Properties
|
|
24
|
+
include Schema::Validation::Dependencies
|
|
25
|
+
|
|
26
|
+
include Schema::Validation::Enum
|
|
27
|
+
include Schema::Validation::Type
|
|
28
|
+
|
|
29
|
+
include Schema::Validation::AllOf
|
|
30
|
+
include Schema::Validation::AnyOf
|
|
31
|
+
include Schema::Validation::OneOf
|
|
32
|
+
include Schema::Validation::Not
|
|
33
|
+
|
|
34
|
+
# @private
|
|
35
|
+
def internal_validate_keywords(result_builder)
|
|
36
|
+
internal_validate_ref(result_builder, throw_result: true)
|
|
37
|
+
|
|
38
|
+
# 5.1. Validation keywords for numeric instances (number and integer)
|
|
39
|
+
|
|
40
|
+
# 5.1.1. multipleOf
|
|
41
|
+
internal_validate_multipleOf(result_builder)
|
|
42
|
+
|
|
43
|
+
# 5.1.2. maximum and exclusiveMaximum
|
|
44
|
+
internal_validate_maximum(result_builder)
|
|
45
|
+
|
|
46
|
+
# 5.1.3. minimum and exclusiveMinimum
|
|
47
|
+
internal_validate_minimum(result_builder)
|
|
48
|
+
|
|
49
|
+
# 5.2. Validation keywords for strings
|
|
50
|
+
|
|
51
|
+
# 5.2.1. maxLength
|
|
52
|
+
internal_validate_maxLength(result_builder)
|
|
53
|
+
|
|
54
|
+
# 5.2.2. minLength
|
|
55
|
+
internal_validate_minLength(result_builder)
|
|
56
|
+
|
|
57
|
+
# 5.2.3. pattern
|
|
58
|
+
internal_validate_pattern(result_builder)
|
|
59
|
+
|
|
60
|
+
# 5.3. Validation keywords for arrays
|
|
61
|
+
|
|
62
|
+
# 5.3.1. additionalItems and items
|
|
63
|
+
internal_validate_items(result_builder)
|
|
64
|
+
|
|
65
|
+
# 5.3.2. maxItems
|
|
66
|
+
internal_validate_maxItems(result_builder)
|
|
67
|
+
|
|
68
|
+
# 5.3.3. minItems
|
|
69
|
+
internal_validate_minItems(result_builder)
|
|
70
|
+
|
|
71
|
+
# 5.3.4. uniqueItems
|
|
72
|
+
internal_validate_uniqueItems(result_builder)
|
|
73
|
+
|
|
74
|
+
# 5.4. Validation keywords for objects
|
|
75
|
+
|
|
76
|
+
# 5.4.1. maxProperties
|
|
77
|
+
internal_validate_maxProperties(result_builder)
|
|
78
|
+
|
|
79
|
+
# 5.4.2. minProperties
|
|
80
|
+
internal_validate_minProperties(result_builder)
|
|
81
|
+
|
|
82
|
+
# 5.4.3. required
|
|
83
|
+
internal_validate_required(result_builder)
|
|
84
|
+
|
|
85
|
+
# 5.4.4. additionalProperties, properties and patternProperties
|
|
86
|
+
internal_validate_properties(result_builder)
|
|
87
|
+
|
|
88
|
+
# 5.4.5. dependencies
|
|
89
|
+
internal_validate_dependencies(result_builder)
|
|
90
|
+
|
|
91
|
+
# 5.5. Validation keywords for any instance type
|
|
92
|
+
|
|
93
|
+
# 5.5.1. enum
|
|
94
|
+
internal_validate_enum(result_builder)
|
|
95
|
+
|
|
96
|
+
# 5.5.2. type
|
|
97
|
+
internal_validate_type(result_builder)
|
|
98
|
+
|
|
99
|
+
# 5.5.3. allOf
|
|
100
|
+
internal_validate_allOf(result_builder)
|
|
101
|
+
|
|
102
|
+
# 5.5.4. anyOf
|
|
103
|
+
internal_validate_anyOf(result_builder)
|
|
104
|
+
|
|
105
|
+
# 5.5.5. oneOf
|
|
106
|
+
internal_validate_oneOf(result_builder)
|
|
107
|
+
|
|
108
|
+
# 5.5.6. not
|
|
109
|
+
internal_validate_not(result_builder)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JSI
|
|
4
|
+
module Schema::Validation::Draft06
|
|
5
|
+
include Schema::Validation::Core
|
|
6
|
+
|
|
7
|
+
include Schema::Validation::Ref
|
|
8
|
+
include Schema::Validation::AllOf
|
|
9
|
+
include Schema::Validation::AnyOf
|
|
10
|
+
include Schema::Validation::OneOf
|
|
11
|
+
include Schema::Validation::Not
|
|
12
|
+
|
|
13
|
+
include Schema::Validation::Items
|
|
14
|
+
include Schema::Validation::Contains
|
|
15
|
+
include Schema::Validation::Properties
|
|
16
|
+
|
|
17
|
+
include Schema::Validation::MultipleOf
|
|
18
|
+
include Schema::Validation::MinMax
|
|
19
|
+
|
|
20
|
+
include Schema::Validation::StringLength
|
|
21
|
+
|
|
22
|
+
include Schema::Validation::Pattern
|
|
23
|
+
|
|
24
|
+
include Schema::Validation::ArrayLength
|
|
25
|
+
include Schema::Validation::UniqueItems
|
|
26
|
+
|
|
27
|
+
include Schema::Validation::MinMaxProperties
|
|
28
|
+
include Schema::Validation::Required
|
|
29
|
+
include Schema::Validation::Dependencies
|
|
30
|
+
include Schema::Validation::PropertyNames
|
|
31
|
+
|
|
32
|
+
include Schema::Validation::Const
|
|
33
|
+
include Schema::Validation::Enum
|
|
34
|
+
|
|
35
|
+
include Schema::Validation::Type
|
|
36
|
+
|
|
37
|
+
# @private
|
|
38
|
+
def internal_validate_keywords(result_builder)
|
|
39
|
+
# json-schema 8. Schema references with $ref
|
|
40
|
+
internal_validate_ref(result_builder, throw_result: true)
|
|
41
|
+
|
|
42
|
+
# json-schema-validation 6.1. multipleOf
|
|
43
|
+
internal_validate_multipleOf(result_builder)
|
|
44
|
+
|
|
45
|
+
# json-schema-validation 6.2. maximum
|
|
46
|
+
internal_validate_maximum(result_builder)
|
|
47
|
+
|
|
48
|
+
# json-schema-validation 6.3. exclusiveMaximum
|
|
49
|
+
internal_validate_exclusiveMaximum(result_builder)
|
|
50
|
+
|
|
51
|
+
# json-schema-validation 6.4. minimum
|
|
52
|
+
internal_validate_minimum(result_builder)
|
|
53
|
+
|
|
54
|
+
# json-schema-validation 6.5. exclusiveMinimum
|
|
55
|
+
internal_validate_exclusiveMinimum(result_builder)
|
|
56
|
+
|
|
57
|
+
# json-schema-validation 6.6. maxLength
|
|
58
|
+
internal_validate_maxLength(result_builder)
|
|
59
|
+
|
|
60
|
+
# json-schema-validation 6.7. minLength
|
|
61
|
+
internal_validate_minLength(result_builder)
|
|
62
|
+
|
|
63
|
+
# json-schema-validation 6.8. pattern
|
|
64
|
+
internal_validate_pattern(result_builder)
|
|
65
|
+
|
|
66
|
+
# json-schema-validation 6.9. items
|
|
67
|
+
# json-schema-validation 6.10. additionalItems
|
|
68
|
+
internal_validate_items(result_builder)
|
|
69
|
+
|
|
70
|
+
# json-schema-validation 6.11. maxItems
|
|
71
|
+
internal_validate_maxItems(result_builder)
|
|
72
|
+
|
|
73
|
+
# json-schema-validation 6.12. minItems
|
|
74
|
+
internal_validate_minItems(result_builder)
|
|
75
|
+
|
|
76
|
+
# json-schema-validation 6.13. uniqueItems
|
|
77
|
+
internal_validate_uniqueItems(result_builder)
|
|
78
|
+
|
|
79
|
+
# json-schema-validation 6.14. contains
|
|
80
|
+
internal_validate_contains(result_builder)
|
|
81
|
+
|
|
82
|
+
# json-schema-validation 6.15. maxProperties
|
|
83
|
+
internal_validate_maxProperties(result_builder)
|
|
84
|
+
|
|
85
|
+
# json-schema-validation 6.16. minProperties
|
|
86
|
+
internal_validate_minProperties(result_builder)
|
|
87
|
+
|
|
88
|
+
# json-schema-validation 6.17. required
|
|
89
|
+
internal_validate_required(result_builder)
|
|
90
|
+
|
|
91
|
+
# json-schema-validation 6.18. properties
|
|
92
|
+
# json-schema-validation 6.19. patternProperties
|
|
93
|
+
# json-schema-validation 6.20. additionalProperties
|
|
94
|
+
internal_validate_properties(result_builder)
|
|
95
|
+
|
|
96
|
+
# json-schema-validation 6.21. dependencies
|
|
97
|
+
internal_validate_dependencies(result_builder)
|
|
98
|
+
|
|
99
|
+
# json-schema-validation 6.22. propertyNames
|
|
100
|
+
internal_validate_propertyNames(result_builder)
|
|
101
|
+
|
|
102
|
+
# json-schema-validation 6.23. enum
|
|
103
|
+
internal_validate_enum(result_builder)
|
|
104
|
+
|
|
105
|
+
# json-schema-validation 6.24. const
|
|
106
|
+
internal_validate_const(result_builder)
|
|
107
|
+
|
|
108
|
+
# json-schema-validation 6.25. type
|
|
109
|
+
internal_validate_type(result_builder)
|
|
110
|
+
|
|
111
|
+
# json-schema-validation 6.26. allOf
|
|
112
|
+
internal_validate_allOf(result_builder)
|
|
113
|
+
# json-schema-validation 6.27. anyOf
|
|
114
|
+
internal_validate_anyOf(result_builder)
|
|
115
|
+
# json-schema-validation 6.28. oneOf
|
|
116
|
+
internal_validate_oneOf(result_builder)
|
|
117
|
+
|
|
118
|
+
# json-schema-validation 6.29. not
|
|
119
|
+
internal_validate_not(result_builder)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JSI
|
|
4
|
+
module Schema::Validation::Draft07
|
|
5
|
+
include Schema::Validation::Core
|
|
6
|
+
|
|
7
|
+
include Schema::Validation::Ref
|
|
8
|
+
|
|
9
|
+
include Schema::Validation::Type
|
|
10
|
+
include Schema::Validation::Enum
|
|
11
|
+
include Schema::Validation::Const
|
|
12
|
+
|
|
13
|
+
include Schema::Validation::MultipleOf
|
|
14
|
+
include Schema::Validation::MinMax
|
|
15
|
+
|
|
16
|
+
include Schema::Validation::StringLength
|
|
17
|
+
include Schema::Validation::Pattern
|
|
18
|
+
|
|
19
|
+
include Schema::Validation::Items
|
|
20
|
+
include Schema::Validation::ArrayLength
|
|
21
|
+
include Schema::Validation::UniqueItems
|
|
22
|
+
include Schema::Validation::Contains
|
|
23
|
+
|
|
24
|
+
include Schema::Validation::MinMaxProperties
|
|
25
|
+
include Schema::Validation::Required
|
|
26
|
+
|
|
27
|
+
include Schema::Validation::Properties
|
|
28
|
+
include Schema::Validation::Dependencies
|
|
29
|
+
include Schema::Validation::PropertyNames
|
|
30
|
+
|
|
31
|
+
include Schema::Validation::IfThenElse
|
|
32
|
+
include Schema::Validation::AllOf
|
|
33
|
+
include Schema::Validation::AnyOf
|
|
34
|
+
include Schema::Validation::OneOf
|
|
35
|
+
include Schema::Validation::Not
|
|
36
|
+
|
|
37
|
+
# @private
|
|
38
|
+
def internal_validate_keywords(result_builder)
|
|
39
|
+
internal_validate_ref(result_builder, throw_result: true)
|
|
40
|
+
|
|
41
|
+
# 6.1. Validation Keywords for Any Instance Type
|
|
42
|
+
|
|
43
|
+
# 6.1.1. type
|
|
44
|
+
internal_validate_type(result_builder)
|
|
45
|
+
|
|
46
|
+
# 6.1.2. enum
|
|
47
|
+
internal_validate_enum(result_builder)
|
|
48
|
+
|
|
49
|
+
# 6.1.3. const
|
|
50
|
+
internal_validate_const(result_builder)
|
|
51
|
+
|
|
52
|
+
# 6.2. Validation Keywords for Numeric Instances (number and integer)
|
|
53
|
+
|
|
54
|
+
# 6.2.1. multipleOf
|
|
55
|
+
internal_validate_multipleOf(result_builder)
|
|
56
|
+
|
|
57
|
+
# 6.2.2. maximum
|
|
58
|
+
internal_validate_maximum(result_builder)
|
|
59
|
+
|
|
60
|
+
# 6.2.3. exclusiveMaximum
|
|
61
|
+
internal_validate_exclusiveMaximum(result_builder)
|
|
62
|
+
|
|
63
|
+
# 6.2.4. minimum
|
|
64
|
+
internal_validate_minimum(result_builder)
|
|
65
|
+
|
|
66
|
+
# 6.2.5. exclusiveMinimum
|
|
67
|
+
internal_validate_exclusiveMinimum(result_builder)
|
|
68
|
+
|
|
69
|
+
# 6.3. Validation Keywords for Strings
|
|
70
|
+
|
|
71
|
+
# 6.3.1. maxLength
|
|
72
|
+
internal_validate_maxLength(result_builder)
|
|
73
|
+
|
|
74
|
+
# 6.3.2. minLength
|
|
75
|
+
internal_validate_minLength(result_builder)
|
|
76
|
+
|
|
77
|
+
# 6.3.3. pattern
|
|
78
|
+
internal_validate_pattern(result_builder)
|
|
79
|
+
|
|
80
|
+
# 6.4. Validation Keywords for Arrays
|
|
81
|
+
|
|
82
|
+
# 6.4.1. items
|
|
83
|
+
# 6.4.2. additionalItems
|
|
84
|
+
internal_validate_items(result_builder)
|
|
85
|
+
|
|
86
|
+
# 6.4.3. maxItems
|
|
87
|
+
internal_validate_maxItems(result_builder)
|
|
88
|
+
|
|
89
|
+
# 6.4.4. minItems
|
|
90
|
+
internal_validate_minItems(result_builder)
|
|
91
|
+
|
|
92
|
+
# 6.4.5. uniqueItems
|
|
93
|
+
internal_validate_uniqueItems(result_builder)
|
|
94
|
+
|
|
95
|
+
# 6.4.6. contains
|
|
96
|
+
internal_validate_contains(result_builder)
|
|
97
|
+
|
|
98
|
+
# 6.5. Validation Keywords for Objects
|
|
99
|
+
|
|
100
|
+
# 6.5.1. maxProperties
|
|
101
|
+
internal_validate_maxProperties(result_builder)
|
|
102
|
+
|
|
103
|
+
# 6.5.2. minProperties
|
|
104
|
+
internal_validate_minProperties(result_builder)
|
|
105
|
+
|
|
106
|
+
# 6.5.3. required
|
|
107
|
+
internal_validate_required(result_builder)
|
|
108
|
+
|
|
109
|
+
# 6.5.4. properties
|
|
110
|
+
# 6.5.5. patternProperties
|
|
111
|
+
# 6.5.6. additionalProperties
|
|
112
|
+
internal_validate_properties(result_builder)
|
|
113
|
+
|
|
114
|
+
# 6.5.7. dependencies
|
|
115
|
+
internal_validate_dependencies(result_builder)
|
|
116
|
+
|
|
117
|
+
# 6.5.8. propertyNames
|
|
118
|
+
internal_validate_propertyNames(result_builder)
|
|
119
|
+
|
|
120
|
+
# 6.6. Keywords for Applying Subschemas Conditionally
|
|
121
|
+
|
|
122
|
+
# 6.6.1. if
|
|
123
|
+
# 6.6.2. then
|
|
124
|
+
# 6.6.3. else
|
|
125
|
+
internal_validate_ifthenelse(result_builder)
|
|
126
|
+
|
|
127
|
+
# 6.7. Keywords for Applying Subschemas With Boolean Logic
|
|
128
|
+
|
|
129
|
+
# 6.7.1. allOf
|
|
130
|
+
internal_validate_allOf(result_builder)
|
|
131
|
+
|
|
132
|
+
# 6.7.2. anyOf
|
|
133
|
+
internal_validate_anyOf(result_builder)
|
|
134
|
+
|
|
135
|
+
# 6.7.3. oneOf
|
|
136
|
+
internal_validate_oneOf(result_builder)
|
|
137
|
+
|
|
138
|
+
# 6.7.4. not
|
|
139
|
+
internal_validate_not(result_builder)
|
|
140
|
+
|
|
141
|
+
# 7. Semantic Validation With "format"
|
|
142
|
+
# TODO
|
|
143
|
+
|
|
144
|
+
# 10. Schema Annotations
|
|
145
|
+
|
|
146
|
+
# 10.1. "title" and "description"
|
|
147
|
+
# TODO
|
|
148
|
+
|
|
149
|
+
# 10.2. "default"
|
|
150
|
+
# TODO
|
|
151
|
+
|
|
152
|
+
# 10.3. "readOnly" and "writeOnly"
|
|
153
|
+
# TODO
|
|
154
|
+
|
|
155
|
+
# 10.4. "examples"
|
|
156
|
+
# TODO
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JSI
|
|
4
|
+
module Schema::Validation::Enum
|
|
5
|
+
# @private
|
|
6
|
+
def internal_validate_enum(result_builder)
|
|
7
|
+
if schema_content.key?('enum')
|
|
8
|
+
value = schema_content['enum']
|
|
9
|
+
# The value of this keyword MUST be an array. This array SHOULD have at least one element.
|
|
10
|
+
# Elements in the array SHOULD be unique.
|
|
11
|
+
if value.respond_to?(:to_ary)
|
|
12
|
+
# An instance validates successfully against this keyword if its value is equal to one of the
|
|
13
|
+
# elements in this keyword's array value.
|
|
14
|
+
result_builder.validate(
|
|
15
|
+
value.include?(result_builder.instance),
|
|
16
|
+
'instance is not equal to any `enum` value',
|
|
17
|
+
keyword: 'enum',
|
|
18
|
+
)
|
|
19
|
+
else
|
|
20
|
+
result_builder.schema_error('`enum` is not an array', 'enum')
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JSI
|
|
4
|
+
module Schema::Validation::IfThenElse
|
|
5
|
+
# @private
|
|
6
|
+
def internal_validate_ifthenelse(result_builder)
|
|
7
|
+
if schema_content.key?('if')
|
|
8
|
+
# This keyword's value MUST be a valid JSON Schema.
|
|
9
|
+
# This validation outcome of this keyword's subschema has no direct effect on the overall validation
|
|
10
|
+
# result. Rather, it controls which of the "then" or "else" keywords are evaluated.
|
|
11
|
+
if_result = result_builder.inplace_subschema_validate(['if'])
|
|
12
|
+
|
|
13
|
+
result_builder.merge_schema_issues(if_result)
|
|
14
|
+
|
|
15
|
+
if if_result.valid?
|
|
16
|
+
if schema_content.key?('then')
|
|
17
|
+
then_result = result_builder.inplace_subschema_validate(['then'])
|
|
18
|
+
result_builder.validate(
|
|
19
|
+
then_result.valid?,
|
|
20
|
+
'instance did not validate against the schema defined by `then` value after validating against the schema defined by the `if` value',
|
|
21
|
+
keyword: 'if',
|
|
22
|
+
results: [then_result],
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
else
|
|
26
|
+
if schema_content.key?('else')
|
|
27
|
+
else_result = result_builder.inplace_subschema_validate(['else'])
|
|
28
|
+
result_builder.validate(
|
|
29
|
+
else_result.valid?,
|
|
30
|
+
'instance did not validate against the schema defined by `else` value after not validating against the schema defined by the `if` value',
|
|
31
|
+
keyword: 'if',
|
|
32
|
+
results: [else_result],
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
else
|
|
37
|
+
if schema_content.key?('then')
|
|
38
|
+
result_builder.schema_warning('`then` has no effect without adjacent `if` keyword', 'then')
|
|
39
|
+
end
|
|
40
|
+
if schema_content.key?('else')
|
|
41
|
+
result_builder.schema_warning('`else` has no effect without adjacent `if` keyword', 'else')
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|