jsi 0.6.0 → 0.8.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 +6 -1
- data/CHANGELOG.md +33 -0
- data/LICENSE.md +1 -1
- data/README.md +29 -23
- data/jsi.gemspec +29 -0
- data/lib/jsi/base/mutability.rb +44 -0
- data/lib/jsi/base/node.rb +348 -0
- data/lib/jsi/base.rb +497 -339
- data/lib/jsi/jsi_coder.rb +19 -17
- data/lib/jsi/metaschema_node/bootstrap_schema.rb +61 -26
- data/lib/jsi/metaschema_node.rb +161 -133
- data/lib/jsi/ptr.rb +80 -47
- data/lib/jsi/schema/application/child_application/contains.rb +11 -2
- data/lib/jsi/schema/application/child_application/draft04.rb +0 -1
- data/lib/jsi/schema/application/child_application/draft06.rb +0 -1
- data/lib/jsi/schema/application/child_application/draft07.rb +0 -1
- data/lib/jsi/schema/application/child_application/items.rb +3 -3
- data/lib/jsi/schema/application/child_application/properties.rb +3 -3
- data/lib/jsi/schema/application/child_application.rb +0 -27
- data/lib/jsi/schema/application/inplace_application/dependencies.rb +1 -1
- data/lib/jsi/schema/application/inplace_application/draft04.rb +0 -1
- data/lib/jsi/schema/application/inplace_application/draft06.rb +0 -1
- data/lib/jsi/schema/application/inplace_application/draft07.rb +0 -1
- data/lib/jsi/schema/application/inplace_application/ifthenelse.rb +3 -3
- data/lib/jsi/schema/application/inplace_application/ref.rb +2 -2
- data/lib/jsi/schema/application/inplace_application/someof.rb +26 -11
- data/lib/jsi/schema/application/inplace_application.rb +0 -32
- data/lib/jsi/schema/draft04.rb +0 -1
- data/lib/jsi/schema/draft06.rb +0 -1
- data/lib/jsi/schema/draft07.rb +0 -1
- data/lib/jsi/schema/ref.rb +46 -19
- data/lib/jsi/schema/schema_ancestor_node.rb +69 -66
- data/lib/jsi/schema/validation/array.rb +3 -3
- data/lib/jsi/schema/validation/const.rb +1 -1
- data/lib/jsi/schema/validation/contains.rb +2 -2
- data/lib/jsi/schema/validation/dependencies.rb +1 -1
- data/lib/jsi/schema/validation/draft04/minmax.rb +8 -6
- data/lib/jsi/schema/validation/draft04.rb +0 -2
- data/lib/jsi/schema/validation/draft06.rb +0 -2
- data/lib/jsi/schema/validation/draft07.rb +0 -2
- data/lib/jsi/schema/validation/enum.rb +1 -1
- data/lib/jsi/schema/validation/ifthenelse.rb +5 -5
- data/lib/jsi/schema/validation/items.rb +7 -7
- data/lib/jsi/schema/validation/not.rb +1 -1
- data/lib/jsi/schema/validation/numeric.rb +5 -5
- data/lib/jsi/schema/validation/object.rb +2 -2
- data/lib/jsi/schema/validation/pattern.rb +2 -2
- data/lib/jsi/schema/validation/properties.rb +7 -7
- data/lib/jsi/schema/validation/property_names.rb +1 -1
- data/lib/jsi/schema/validation/ref.rb +2 -2
- data/lib/jsi/schema/validation/required.rb +1 -1
- data/lib/jsi/schema/validation/someof.rb +3 -3
- data/lib/jsi/schema/validation/string.rb +2 -2
- data/lib/jsi/schema/validation/type.rb +1 -1
- data/lib/jsi/schema/validation.rb +1 -3
- data/lib/jsi/schema.rb +443 -226
- data/lib/jsi/schema_classes.rb +241 -147
- data/lib/jsi/schema_registry.rb +78 -19
- data/lib/jsi/schema_set.rb +114 -28
- data/lib/jsi/simple_wrap.rb +18 -4
- data/lib/jsi/util/private/attr_struct.rb +141 -0
- data/lib/jsi/util/private/memo_map.rb +75 -0
- data/lib/jsi/util/private.rb +185 -0
- data/lib/jsi/{typelike_modules.rb → util/typelike.rb} +79 -105
- data/lib/jsi/util.rb +157 -153
- data/lib/jsi/validation/error.rb +4 -0
- data/lib/jsi/validation/result.rb +18 -32
- data/lib/jsi/version.rb +1 -1
- data/lib/jsi.rb +65 -39
- data/lib/schemas/json-schema.org/draft-04/schema.rb +160 -3
- data/lib/schemas/json-schema.org/draft-06/schema.rb +162 -3
- data/lib/schemas/json-schema.org/draft-07/schema.rb +189 -3
- metadata +27 -11
- data/lib/jsi/metaschema.rb +0 -7
- data/lib/jsi/pathed_node.rb +0 -116
- data/lib/jsi/schema/validation/core.rb +0 -39
- data/lib/jsi/util/attr_struct.rb +0 -106
data/lib/jsi/schema/ref.rb
CHANGED
@@ -1,30 +1,45 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module JSI
|
4
|
-
# JSI::Schema::Ref is a reference to
|
5
|
-
#
|
4
|
+
# A JSI::Schema::Ref is a reference to a schema identified by a URI, typically from
|
5
|
+
# a `$ref` keyword of a schema.
|
6
6
|
class Schema::Ref
|
7
|
-
# @param ref [String]
|
8
|
-
# @param ref_schema [JSI::Schema]
|
9
|
-
|
7
|
+
# @param ref [String] A reference URI - typically the `$ref` value of the ref_schema
|
8
|
+
# @param ref_schema [JSI::Schema] A schema from which the reference originated.
|
9
|
+
#
|
10
|
+
# If the ref URI consists of only a fragment, it is resolved from the `ref_schema`'s
|
11
|
+
# {Schema#schema_resource_root}. Otherwise the resource is found in the `ref_schema`'s
|
12
|
+
# {SchemaAncestorNode#jsi_schema_registry #jsi_schema_registry} (and any fragment is resolved from there).
|
13
|
+
# @param schema_registry [SchemaRegistry] The registry in which the resource this ref refers to will be found.
|
14
|
+
# This should only be specified in the absence of a `ref_schema`.
|
15
|
+
# If neither is specified, {JSI.schema_registry} is used.
|
16
|
+
def initialize(ref, ref_schema: nil, schema_registry: nil)
|
10
17
|
raise(ArgumentError, "ref is not a string") unless ref.respond_to?(:to_str)
|
11
18
|
@ref = ref
|
12
|
-
@ref_uri =
|
19
|
+
@ref_uri = Util.uri(ref)
|
13
20
|
@ref_schema = ref_schema ? Schema.ensure_schema(ref_schema) : nil
|
21
|
+
@schema_registry = schema_registry || (ref_schema ? ref_schema.jsi_schema_registry : JSI.schema_registry)
|
22
|
+
@deref_schema = nil
|
14
23
|
end
|
15
24
|
|
25
|
+
# @return [String]
|
16
26
|
attr_reader :ref
|
17
27
|
|
28
|
+
# @return [Addressable::URI]
|
18
29
|
attr_reader :ref_uri
|
19
30
|
|
31
|
+
# @return [Schema, nil]
|
20
32
|
attr_reader :ref_schema
|
21
33
|
|
34
|
+
# @return [SchemaRegistry, nil]
|
35
|
+
attr_reader(:schema_registry)
|
36
|
+
|
22
37
|
# finds the schema this ref points to
|
23
38
|
# @return [JSI::Schema]
|
24
39
|
# @raise [JSI::Schema::NotASchemaError] when the thing this ref points to is not a schema
|
25
40
|
# @raise [JSI::Schema::ReferenceError] when this reference cannot be resolved
|
26
41
|
def deref_schema
|
27
|
-
return @deref_schema if
|
42
|
+
return @deref_schema if @deref_schema
|
28
43
|
|
29
44
|
schema_resource_root = nil
|
30
45
|
check_schema_resource_root = -> {
|
@@ -36,7 +51,7 @@ module JSI
|
|
36
51
|
end
|
37
52
|
}
|
38
53
|
|
39
|
-
ref_uri_nofrag = ref_uri.merge(fragment: nil)
|
54
|
+
ref_uri_nofrag = ref_uri.merge(fragment: nil).freeze
|
40
55
|
|
41
56
|
if ref_uri_nofrag.empty?
|
42
57
|
unless ref_schema
|
@@ -49,28 +64,34 @@ module JSI
|
|
49
64
|
# the URI only consists of a fragment (or is empty).
|
50
65
|
# for a fragment pointer, resolve using Schema#resource_root_subschema on the ref_schema.
|
51
66
|
# for a fragment anchor, bootstrap does not support anchors; otherwise use the ref_schema's schema_resource_root.
|
52
|
-
schema_resource_root = ref_schema.is_a?(
|
67
|
+
schema_resource_root = ref_schema.is_a?(MetaSchemaNode::BootstrapSchema) ? nil : ref_schema.schema_resource_root
|
53
68
|
resolve_fragment_ptr = ref_schema.method(:resource_root_subschema)
|
54
69
|
else
|
55
70
|
# find the schema_resource_root from the non-fragment URI. we will resolve any fragment, either pointer or anchor, from there.
|
56
|
-
schema_resource_root = nil
|
57
71
|
|
58
72
|
if ref_uri_nofrag.absolute?
|
59
73
|
ref_abs_uri = ref_uri_nofrag
|
60
74
|
elsif ref_schema && ref_schema.jsi_resource_ancestor_uri
|
61
|
-
ref_abs_uri = ref_schema.jsi_resource_ancestor_uri.join(ref_uri_nofrag)
|
75
|
+
ref_abs_uri = ref_schema.jsi_resource_ancestor_uri.join(ref_uri_nofrag).freeze
|
62
76
|
else
|
63
77
|
ref_abs_uri = nil
|
64
78
|
end
|
65
79
|
if ref_abs_uri
|
66
|
-
|
80
|
+
unless schema_registry
|
81
|
+
raise(Schema::ReferenceError, [
|
82
|
+
"could not resolve remote ref with no schema_registry specified",
|
83
|
+
"ref URI: #{ref_uri.to_s}",
|
84
|
+
("from: #{ref_schema.pretty_inspect.chomp}" if ref_schema),
|
85
|
+
].compact.join("\n"))
|
86
|
+
end
|
87
|
+
schema_resource_root = schema_registry.find(ref_abs_uri)
|
67
88
|
end
|
68
89
|
|
69
90
|
unless schema_resource_root
|
70
91
|
# HAX for how google does refs and ids
|
71
92
|
if ref_schema && ref_schema.jsi_document.respond_to?(:to_hash) && ref_schema.jsi_document['schemas'].respond_to?(:to_hash)
|
72
|
-
ref_schema.jsi_document['schemas'].
|
73
|
-
if Addressable::URI.parse(
|
93
|
+
ref_schema.jsi_document['schemas'].each do |k, v|
|
94
|
+
if Addressable::URI.parse(v['id']) == ref_uri_nofrag
|
74
95
|
schema_resource_root = ref_schema.resource_root_subschema(['schemas', k])
|
75
96
|
end
|
76
97
|
end
|
@@ -84,7 +105,7 @@ module JSI
|
|
84
105
|
else
|
85
106
|
# Note: Schema#resource_root_subschema will reinstantiate nonschemas as schemas.
|
86
107
|
# not implemented for remote refs when the schema_resource_root is not a schema.
|
87
|
-
resolve_fragment_ptr = -> (ptr) {
|
108
|
+
resolve_fragment_ptr = -> (ptr) { schema_resource_root.jsi_descendent_node(ptr) }
|
88
109
|
end
|
89
110
|
end
|
90
111
|
|
@@ -137,7 +158,11 @@ module JSI
|
|
137
158
|
|
138
159
|
# @return [String]
|
139
160
|
def inspect
|
140
|
-
|
161
|
+
-%Q(\#<#{self.class.name} #{ref}>)
|
162
|
+
end
|
163
|
+
|
164
|
+
def to_s
|
165
|
+
inspect
|
141
166
|
end
|
142
167
|
|
143
168
|
# pretty-prints a representation of self to the given printer
|
@@ -150,10 +175,12 @@ module JSI
|
|
150
175
|
q.text '>'
|
151
176
|
end
|
152
177
|
|
153
|
-
#
|
178
|
+
# see {Util::Private::FingerprintHash}
|
179
|
+
# @api private
|
154
180
|
def jsi_fingerprint
|
155
|
-
{class: self.class, ref: ref, ref_schema: ref_schema}
|
181
|
+
{class: self.class, ref: ref, ref_schema: ref_schema}.freeze
|
156
182
|
end
|
157
|
-
|
183
|
+
|
184
|
+
include(Util::FingerprintHash::Immutable)
|
158
185
|
end
|
159
186
|
end
|
@@ -4,39 +4,49 @@ module JSI
|
|
4
4
|
# a node in a document which may contain a schema somewhere within is extended with SchemaAncestorNode, for
|
5
5
|
# tracking things necessary for a schema to function correctly
|
6
6
|
module Schema::SchemaAncestorNode
|
7
|
+
if Util::LAST_ARGUMENT_AS_KEYWORD_PARAMETERS
|
8
|
+
def initialize(*)
|
9
|
+
super
|
10
|
+
jsi_schema_ancestor_node_initialize
|
11
|
+
end
|
12
|
+
else
|
13
|
+
def initialize(*, **)
|
14
|
+
super
|
15
|
+
jsi_schema_ancestor_node_initialize
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
7
19
|
# the base URI used to resolve the ids of schemas at or below this JSI.
|
8
20
|
# this is always an absolute URI (with no fragment).
|
9
|
-
#
|
10
|
-
# @private
|
21
|
+
# This may be the absolute schema URI of an ancestor schema or the URI from which the document was retrieved.
|
22
|
+
# @api private
|
11
23
|
# @return [Addressable::URI, nil]
|
12
24
|
attr_reader :jsi_schema_base_uri
|
13
25
|
|
14
26
|
# resources which are ancestors of this JSI in the document. this does not include self.
|
15
|
-
# @private
|
27
|
+
# @api private
|
16
28
|
# @return [Array<JSI::Schema>]
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
29
|
+
attr_reader :jsi_schema_resource_ancestors
|
30
|
+
|
31
|
+
# See {SchemaSet#new_jsi} param `schema_registry`
|
32
|
+
# @return [SchemaRegistry]
|
33
|
+
attr_reader(:jsi_schema_registry)
|
21
34
|
|
22
35
|
# the URI of the resource containing this node.
|
23
36
|
# this is always an absolute URI (with no fragment).
|
24
|
-
#
|
37
|
+
# If this node is a schema with an id, this is its absolute URI; otherwise an ancestor resource's URI,
|
25
38
|
# or nil if not contained by a resource with a URI.
|
26
39
|
# @return [Addressable::URI, nil]
|
27
40
|
def jsi_resource_ancestor_uri
|
28
|
-
|
29
|
-
schema_absolute_uri
|
30
|
-
else
|
31
|
-
jsi_schema_base_uri
|
32
|
-
end
|
41
|
+
(is_a?(Schema) && schema_absolute_uri) || jsi_schema_base_uri
|
33
42
|
end
|
34
43
|
|
35
|
-
#
|
44
|
+
# The schema at or below this node with the given anchor.
|
45
|
+
# If no schema has that anchor (or multiple schemas do, incorrectly), nil.
|
36
46
|
#
|
37
47
|
# @return [JSI::Schema, nil]
|
38
48
|
def jsi_anchor_subschema(anchor)
|
39
|
-
subschemas =
|
49
|
+
subschemas = @anchor_subschemas_map[anchor: anchor]
|
40
50
|
if subschemas.size == 1
|
41
51
|
subschemas.first
|
42
52
|
else
|
@@ -44,76 +54,69 @@ module JSI
|
|
44
54
|
end
|
45
55
|
end
|
46
56
|
|
47
|
-
# schemas at or below node with the given anchor.
|
57
|
+
# All schemas at or below this node with the given anchor.
|
48
58
|
#
|
49
|
-
# @return [
|
59
|
+
# @return [Set<JSI::Schema>]
|
50
60
|
def jsi_anchor_subschemas(anchor)
|
51
|
-
|
61
|
+
@anchor_subschemas_map[anchor: anchor]
|
52
62
|
end
|
53
63
|
|
54
64
|
private
|
55
65
|
|
56
|
-
def
|
57
|
-
@
|
66
|
+
def jsi_schema_ancestor_node_initialize
|
67
|
+
@anchor_subschemas_map = jsi_memomap(&method(:jsi_anchor_subschemas_compute))
|
58
68
|
end
|
59
69
|
|
70
|
+
attr_writer :jsi_document
|
71
|
+
|
60
72
|
def jsi_ptr=(jsi_ptr)
|
61
|
-
unless jsi_ptr.is_a?(Ptr)
|
62
|
-
raise(TypeError, "jsi_ptr must be a JSI::Ptr; got: #{jsi_ptr.inspect}")
|
63
|
-
end
|
73
|
+
#chkbug raise(Bug, "jsi_ptr not #{Ptr}: #{jsi_ptr}") unless jsi_ptr.is_a?(Ptr)
|
64
74
|
@jsi_ptr = jsi_ptr
|
65
75
|
end
|
66
76
|
|
67
77
|
def jsi_schema_base_uri=(jsi_schema_base_uri)
|
68
|
-
if jsi_schema_base_uri
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
unless @jsi_schema_base_uri.absolute? && !@jsi_schema_base_uri.fragment
|
74
|
-
raise(ArgumentError, "jsi_schema_base_uri must be an absolute URI with no fragment; got: #{jsi_schema_base_uri.inspect}")
|
75
|
-
end
|
76
|
-
else
|
77
|
-
@jsi_schema_base_uri = nil
|
78
|
-
end
|
78
|
+
#chkbug raise(Bug) if jsi_schema_base_uri && !jsi_schema_base_uri.is_a?(Addressable::URI)
|
79
|
+
#chkbug raise(Bug) if jsi_schema_base_uri && !jsi_schema_base_uri.absolute?
|
80
|
+
#chkbug raise(Bug) if jsi_schema_base_uri && jsi_schema_base_uri.fragment
|
81
|
+
|
82
|
+
@jsi_schema_base_uri = jsi_schema_base_uri
|
79
83
|
end
|
80
84
|
|
81
85
|
def jsi_schema_resource_ancestors=(jsi_schema_resource_ancestors)
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
end
|
104
|
-
|
105
|
-
@jsi_schema_resource_ancestors = jsi_schema_resource_ancestors.to_ary.freeze
|
106
|
-
else
|
107
|
-
@jsi_schema_resource_ancestors = [].freeze
|
108
|
-
end
|
86
|
+
#chkbug raise(Bug) unless jsi_schema_resource_ancestors.respond_to?(:to_ary)
|
87
|
+
#chkbug jsi_schema_resource_ancestors.each { |a| Schema.ensure_schema(a) }
|
88
|
+
#chkbug # sanity check the ancestors are in order
|
89
|
+
#chkbug last_anc_ptr = nil
|
90
|
+
#chkbug jsi_schema_resource_ancestors.each do |anc|
|
91
|
+
#chkbug if last_anc_ptr.nil?
|
92
|
+
#chkbug # pass
|
93
|
+
#chkbug elsif last_anc_ptr == anc.jsi_ptr
|
94
|
+
#chkbug raise(Bug, "duplicate ancestors in #{jsi_schema_resource_ancestors.pretty_inspect}")
|
95
|
+
#chkbug elsif !last_anc_ptr.contains?(anc.jsi_ptr)
|
96
|
+
#chkbug raise(Bug, "ancestor ptr #{anc.jsi_ptr} not contained by previous: #{last_anc_ptr} in #{jsi_schema_resource_ancestors.pretty_inspect}")
|
97
|
+
#chkbug end
|
98
|
+
#chkbug if anc.jsi_ptr == jsi_ptr
|
99
|
+
#chkbug raise(Bug, "ancestor is self")
|
100
|
+
#chkbug elsif !anc.jsi_ptr.ancestor_of?(jsi_ptr)
|
101
|
+
#chkbug raise(Bug, "ancestor does not contain self")
|
102
|
+
#chkbug end
|
103
|
+
#chkbug last_anc_ptr = anc.jsi_ptr
|
104
|
+
#chkbug end
|
105
|
+
|
106
|
+
@jsi_schema_resource_ancestors = jsi_schema_resource_ancestors
|
109
107
|
end
|
110
108
|
|
111
|
-
|
112
|
-
|
113
|
-
|
109
|
+
attr_writer(:jsi_schema_registry)
|
110
|
+
|
111
|
+
def jsi_anchor_subschemas_compute(anchor: )
|
112
|
+
jsi_each_descendent_node.select do |node|
|
114
113
|
node.is_a?(Schema) && node.respond_to?(:anchor) && node.anchor == anchor
|
115
|
-
end.freeze
|
116
|
-
|
114
|
+
end.to_set.freeze
|
115
|
+
end
|
116
|
+
|
117
|
+
# @return [Util::MemoMap]
|
118
|
+
def jsi_memomap(**options, &block)
|
119
|
+
jsi_memomap_class.new(**options, &block)
|
117
120
|
end
|
118
121
|
end
|
119
122
|
end
|
@@ -4,7 +4,7 @@ module JSI
|
|
4
4
|
module Schema::Validation::ArrayLength
|
5
5
|
# @private
|
6
6
|
def internal_validate_maxItems(result_builder)
|
7
|
-
if
|
7
|
+
if keyword?('maxItems')
|
8
8
|
value = schema_content['maxItems']
|
9
9
|
# The value of this keyword MUST be a non-negative integer.
|
10
10
|
if internal_integer?(value) && value >= 0
|
@@ -24,7 +24,7 @@ module JSI
|
|
24
24
|
|
25
25
|
# @private
|
26
26
|
def internal_validate_minItems(result_builder)
|
27
|
-
if
|
27
|
+
if keyword?('minItems')
|
28
28
|
value = schema_content['minItems']
|
29
29
|
# The value of this keyword MUST be a non-negative integer.
|
30
30
|
if internal_integer?(value) && value >= 0
|
@@ -45,7 +45,7 @@ module JSI
|
|
45
45
|
module Schema::Validation::UniqueItems
|
46
46
|
# @private
|
47
47
|
def internal_validate_uniqueItems(result_builder)
|
48
|
-
if
|
48
|
+
if keyword?('uniqueItems')
|
49
49
|
value = schema_content['uniqueItems']
|
50
50
|
# The value of this keyword MUST be a boolean.
|
51
51
|
if value == false
|
@@ -4,7 +4,7 @@ module JSI
|
|
4
4
|
module Schema::Validation::Const
|
5
5
|
# @private
|
6
6
|
def internal_validate_const(result_builder)
|
7
|
-
if
|
7
|
+
if keyword?('const')
|
8
8
|
value = schema_content['const']
|
9
9
|
# The value of this keyword MAY be of any type, including null.
|
10
10
|
# An instance validates successfully against this keyword if its value is equal to the value of
|
@@ -4,13 +4,13 @@ module JSI
|
|
4
4
|
module Schema::Validation::Contains
|
5
5
|
# @private
|
6
6
|
def internal_validate_contains(result_builder)
|
7
|
-
if
|
7
|
+
if keyword?('contains')
|
8
8
|
# An array instance is valid against "contains" if at least one of its elements is valid against
|
9
9
|
# the given schema.
|
10
10
|
if result_builder.instance.respond_to?(:to_ary)
|
11
11
|
results = {}
|
12
12
|
result_builder.instance.each_index do |i|
|
13
|
-
results[i] = result_builder.child_subschema_validate(['contains']
|
13
|
+
results[i] = result_builder.child_subschema_validate(i, ['contains'])
|
14
14
|
end
|
15
15
|
result_builder.validate(
|
16
16
|
results.values.any?(&:valid?),
|
@@ -4,7 +4,7 @@ module JSI
|
|
4
4
|
module Schema::Validation::Dependencies
|
5
5
|
# @private
|
6
6
|
def internal_validate_dependencies(result_builder)
|
7
|
-
if
|
7
|
+
if keyword?('dependencies')
|
8
8
|
value = schema_content['dependencies']
|
9
9
|
# This keyword's value MUST be an object. Each property specifies a dependency. Each dependency
|
10
10
|
# value MUST be an array or a valid JSON Schema.
|
@@ -4,18 +4,19 @@ module JSI
|
|
4
4
|
module Schema::Validation::Draft04::MinMax
|
5
5
|
# @private
|
6
6
|
def internal_validate_maximum(result_builder)
|
7
|
-
if
|
7
|
+
if keyword?('exclusiveMaximum')
|
8
8
|
value = schema_content['exclusiveMaximum']
|
9
9
|
# The value of "exclusiveMaximum" MUST be a boolean.
|
10
10
|
unless [true, false].include?(value)
|
11
11
|
result_builder.schema_error('`exclusiveMaximum` is not true or false', 'exclusiveMaximum')
|
12
12
|
end
|
13
|
-
|
13
|
+
#> If "exclusiveMaximum" is present, "maximum" MUST also be present.
|
14
|
+
if !keyword?('maximum')
|
14
15
|
result_builder.schema_error('`exclusiveMaximum` has no effect without adjacent `maximum` keyword', 'exclusiveMaximum')
|
15
16
|
end
|
16
17
|
end
|
17
18
|
|
18
|
-
if
|
19
|
+
if keyword?('maximum')
|
19
20
|
value = schema_content['maximum']
|
20
21
|
# The value of "maximum" MUST be a JSON number.
|
21
22
|
if value.is_a?(Numeric)
|
@@ -47,18 +48,19 @@ module JSI
|
|
47
48
|
|
48
49
|
# @private
|
49
50
|
def internal_validate_minimum(result_builder)
|
50
|
-
if
|
51
|
+
if keyword?('exclusiveMinimum')
|
51
52
|
value = schema_content['exclusiveMinimum']
|
52
53
|
# The value of "exclusiveMinimum" MUST be a boolean.
|
53
54
|
unless [true, false].include?(value)
|
54
55
|
result_builder.schema_error('`exclusiveMinimum` is not true or false', 'exclusiveMinimum')
|
55
56
|
end
|
56
|
-
|
57
|
+
#> If "exclusiveMinimum" is present, "minimum" MUST also be present.
|
58
|
+
if !keyword?('minimum')
|
57
59
|
result_builder.schema_error('`exclusiveMinimum` has no effect without adjacent `minimum` keyword', 'exclusiveMinimum')
|
58
60
|
end
|
59
61
|
end
|
60
62
|
|
61
|
-
if
|
63
|
+
if keyword?('minimum')
|
62
64
|
value = schema_content['minimum']
|
63
65
|
# The value of "minimum" MUST be a JSON number.
|
64
66
|
if value.is_a?(Numeric)
|
@@ -4,7 +4,7 @@ module JSI
|
|
4
4
|
module Schema::Validation::Enum
|
5
5
|
# @private
|
6
6
|
def internal_validate_enum(result_builder)
|
7
|
-
if
|
7
|
+
if keyword?('enum')
|
8
8
|
value = schema_content['enum']
|
9
9
|
# The value of this keyword MUST be an array. This array SHOULD have at least one element.
|
10
10
|
# Elements in the array SHOULD be unique.
|
@@ -4,7 +4,7 @@ module JSI
|
|
4
4
|
module Schema::Validation::IfThenElse
|
5
5
|
# @private
|
6
6
|
def internal_validate_ifthenelse(result_builder)
|
7
|
-
if
|
7
|
+
if keyword?('if')
|
8
8
|
# This keyword's value MUST be a valid JSON Schema.
|
9
9
|
# This validation outcome of this keyword's subschema has no direct effect on the overall validation
|
10
10
|
# result. Rather, it controls which of the "then" or "else" keywords are evaluated.
|
@@ -13,7 +13,7 @@ module JSI
|
|
13
13
|
result_builder.merge_schema_issues(if_result)
|
14
14
|
|
15
15
|
if if_result.valid?
|
16
|
-
if
|
16
|
+
if keyword?('then')
|
17
17
|
then_result = result_builder.inplace_subschema_validate(['then'])
|
18
18
|
result_builder.validate(
|
19
19
|
then_result.valid?,
|
@@ -23,7 +23,7 @@ module JSI
|
|
23
23
|
)
|
24
24
|
end
|
25
25
|
else
|
26
|
-
if
|
26
|
+
if keyword?('else')
|
27
27
|
else_result = result_builder.inplace_subschema_validate(['else'])
|
28
28
|
result_builder.validate(
|
29
29
|
else_result.valid?,
|
@@ -34,10 +34,10 @@ module JSI
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
else
|
37
|
-
if
|
37
|
+
if keyword?('then')
|
38
38
|
result_builder.schema_warning('`then` has no effect without adjacent `if` keyword', 'then')
|
39
39
|
end
|
40
|
-
if
|
40
|
+
if keyword?('else')
|
41
41
|
result_builder.schema_warning('`else` has no effect without adjacent `if` keyword', 'else')
|
42
42
|
end
|
43
43
|
end
|
@@ -4,7 +4,7 @@ module JSI
|
|
4
4
|
module Schema::Validation::Items
|
5
5
|
# @private
|
6
6
|
def internal_validate_items(result_builder)
|
7
|
-
if
|
7
|
+
if keyword?('items')
|
8
8
|
value = schema_content['items']
|
9
9
|
# The value of "items" MUST be either a valid JSON Schema or an array of valid JSON Schemas.
|
10
10
|
if value.respond_to?(:to_ary)
|
@@ -14,9 +14,9 @@ module JSI
|
|
14
14
|
results = {}
|
15
15
|
result_builder.instance.each_index do |i|
|
16
16
|
if i < value.size
|
17
|
-
results[i] = result_builder.child_subschema_validate(['items', i]
|
18
|
-
elsif
|
19
|
-
results[i] = result_builder.child_subschema_validate(['additionalItems']
|
17
|
+
results[i] = result_builder.child_subschema_validate(i, ['items', i])
|
18
|
+
elsif keyword?('additionalItems')
|
19
|
+
results[i] = result_builder.child_subschema_validate(i, ['additionalItems'])
|
20
20
|
end
|
21
21
|
end
|
22
22
|
result_builder.validate(
|
@@ -31,7 +31,7 @@ module JSI
|
|
31
31
|
# against that schema.
|
32
32
|
if result_builder.instance.respond_to?(:to_ary)
|
33
33
|
results = result_builder.instance.each_index.map do |i|
|
34
|
-
result_builder.child_subschema_validate(['items']
|
34
|
+
result_builder.child_subschema_validate(i, ['items'])
|
35
35
|
end
|
36
36
|
result_builder.validate(
|
37
37
|
results.all?(&:valid?),
|
@@ -40,12 +40,12 @@ module JSI
|
|
40
40
|
results: results,
|
41
41
|
)
|
42
42
|
end
|
43
|
-
if
|
43
|
+
if keyword?('additionalItems')
|
44
44
|
result_builder.schema_warning('`additionalItems` has no effect when adjacent `items` keyword is not an array', 'items')
|
45
45
|
end
|
46
46
|
end
|
47
47
|
else
|
48
|
-
if
|
48
|
+
if keyword?('additionalItems')
|
49
49
|
result_builder.schema_warning('`additionalItems` has no effect without adjacent `items` keyword', 'items')
|
50
50
|
end
|
51
51
|
end
|
@@ -4,7 +4,7 @@ module JSI
|
|
4
4
|
module Schema::Validation::Not
|
5
5
|
# @private
|
6
6
|
def internal_validate_not(result_builder)
|
7
|
-
if
|
7
|
+
if keyword?('not')
|
8
8
|
# This keyword's value MUST be a valid JSON Schema.
|
9
9
|
# An instance is valid against this keyword if it fails to validate successfully against the schema
|
10
10
|
# defined by this keyword.
|
@@ -4,7 +4,7 @@ module JSI
|
|
4
4
|
module Schema::Validation::MultipleOf
|
5
5
|
# @private
|
6
6
|
def internal_validate_multipleOf(result_builder)
|
7
|
-
if
|
7
|
+
if keyword?('multipleOf')
|
8
8
|
value = schema_content['multipleOf']
|
9
9
|
# The value of "multipleOf" MUST be a number, strictly greater than 0.
|
10
10
|
if value.is_a?(Numeric) && value > 0
|
@@ -36,7 +36,7 @@ module JSI
|
|
36
36
|
module Schema::Validation::MinMax
|
37
37
|
# @private
|
38
38
|
def internal_validate_maximum(result_builder)
|
39
|
-
if
|
39
|
+
if keyword?('maximum')
|
40
40
|
value = schema_content['maximum']
|
41
41
|
# The value of "maximum" MUST be a number, representing an inclusive upper limit for a numeric instance.
|
42
42
|
if value.is_a?(Numeric)
|
@@ -57,7 +57,7 @@ module JSI
|
|
57
57
|
|
58
58
|
# @private
|
59
59
|
def internal_validate_exclusiveMaximum(result_builder)
|
60
|
-
if
|
60
|
+
if keyword?('exclusiveMaximum')
|
61
61
|
value = schema_content['exclusiveMaximum']
|
62
62
|
# The value of "exclusiveMaximum" MUST be number, representing an exclusive upper limit for a numeric instance.
|
63
63
|
if value.is_a?(Numeric)
|
@@ -78,7 +78,7 @@ module JSI
|
|
78
78
|
|
79
79
|
# @private
|
80
80
|
def internal_validate_minimum(result_builder)
|
81
|
-
if
|
81
|
+
if keyword?('minimum')
|
82
82
|
value = schema_content['minimum']
|
83
83
|
# The value of "minimum" MUST be a number, representing an inclusive lower limit for a numeric instance.
|
84
84
|
if value.is_a?(Numeric)
|
@@ -99,7 +99,7 @@ module JSI
|
|
99
99
|
|
100
100
|
# @private
|
101
101
|
def internal_validate_exclusiveMinimum(result_builder)
|
102
|
-
if
|
102
|
+
if keyword?('exclusiveMinimum')
|
103
103
|
value = schema_content['exclusiveMinimum']
|
104
104
|
# The value of "exclusiveMinimum" MUST be number, representing an exclusive lower limit for a numeric instance.
|
105
105
|
if value.is_a?(Numeric)
|
@@ -4,7 +4,7 @@ module JSI
|
|
4
4
|
module Schema::Validation::MinMaxProperties
|
5
5
|
# @private
|
6
6
|
def internal_validate_maxProperties(result_builder)
|
7
|
-
if
|
7
|
+
if keyword?('maxProperties')
|
8
8
|
value = schema_content['maxProperties']
|
9
9
|
# The value of this keyword MUST be a non-negative integer.
|
10
10
|
if internal_integer?(value) && value >= 0
|
@@ -24,7 +24,7 @@ module JSI
|
|
24
24
|
|
25
25
|
# @private
|
26
26
|
def internal_validate_minProperties(result_builder)
|
27
|
-
if
|
27
|
+
if keyword?('minProperties')
|
28
28
|
value = schema_content['minProperties']
|
29
29
|
# The value of this keyword MUST be a non-negative integer.
|
30
30
|
if internal_integer?(value) && value >= 0
|
@@ -4,7 +4,7 @@ module JSI
|
|
4
4
|
module Schema::Validation::Pattern
|
5
5
|
# @private
|
6
6
|
def internal_validate_pattern(result_builder)
|
7
|
-
if
|
7
|
+
if keyword?('pattern')
|
8
8
|
value = schema_content['pattern']
|
9
9
|
# The value of this keyword MUST be a string.
|
10
10
|
if value.respond_to?(:to_str)
|
@@ -22,7 +22,7 @@ module JSI
|
|
22
22
|
keyword: 'pattern',
|
23
23
|
)
|
24
24
|
rescue RegexpError => e
|
25
|
-
result_builder.schema_error("`pattern` is not a valid regular expression: #{e.message}", 'pattern')
|
25
|
+
result_builder.schema_error(-"`pattern` is not a valid regular expression: #{e.message}", 'pattern')
|
26
26
|
end
|
27
27
|
end
|
28
28
|
else
|