jsi 0.6.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +6 -1
  3. data/CHANGELOG.md +33 -0
  4. data/LICENSE.md +1 -1
  5. data/README.md +29 -23
  6. data/jsi.gemspec +29 -0
  7. data/lib/jsi/base/mutability.rb +44 -0
  8. data/lib/jsi/base/node.rb +348 -0
  9. data/lib/jsi/base.rb +497 -339
  10. data/lib/jsi/jsi_coder.rb +19 -17
  11. data/lib/jsi/metaschema_node/bootstrap_schema.rb +61 -26
  12. data/lib/jsi/metaschema_node.rb +161 -133
  13. data/lib/jsi/ptr.rb +80 -47
  14. data/lib/jsi/schema/application/child_application/contains.rb +11 -2
  15. data/lib/jsi/schema/application/child_application/draft04.rb +0 -1
  16. data/lib/jsi/schema/application/child_application/draft06.rb +0 -1
  17. data/lib/jsi/schema/application/child_application/draft07.rb +0 -1
  18. data/lib/jsi/schema/application/child_application/items.rb +3 -3
  19. data/lib/jsi/schema/application/child_application/properties.rb +3 -3
  20. data/lib/jsi/schema/application/child_application.rb +0 -27
  21. data/lib/jsi/schema/application/inplace_application/dependencies.rb +1 -1
  22. data/lib/jsi/schema/application/inplace_application/draft04.rb +0 -1
  23. data/lib/jsi/schema/application/inplace_application/draft06.rb +0 -1
  24. data/lib/jsi/schema/application/inplace_application/draft07.rb +0 -1
  25. data/lib/jsi/schema/application/inplace_application/ifthenelse.rb +3 -3
  26. data/lib/jsi/schema/application/inplace_application/ref.rb +2 -2
  27. data/lib/jsi/schema/application/inplace_application/someof.rb +26 -11
  28. data/lib/jsi/schema/application/inplace_application.rb +0 -32
  29. data/lib/jsi/schema/draft04.rb +0 -1
  30. data/lib/jsi/schema/draft06.rb +0 -1
  31. data/lib/jsi/schema/draft07.rb +0 -1
  32. data/lib/jsi/schema/ref.rb +46 -19
  33. data/lib/jsi/schema/schema_ancestor_node.rb +69 -66
  34. data/lib/jsi/schema/validation/array.rb +3 -3
  35. data/lib/jsi/schema/validation/const.rb +1 -1
  36. data/lib/jsi/schema/validation/contains.rb +2 -2
  37. data/lib/jsi/schema/validation/dependencies.rb +1 -1
  38. data/lib/jsi/schema/validation/draft04/minmax.rb +8 -6
  39. data/lib/jsi/schema/validation/draft04.rb +0 -2
  40. data/lib/jsi/schema/validation/draft06.rb +0 -2
  41. data/lib/jsi/schema/validation/draft07.rb +0 -2
  42. data/lib/jsi/schema/validation/enum.rb +1 -1
  43. data/lib/jsi/schema/validation/ifthenelse.rb +5 -5
  44. data/lib/jsi/schema/validation/items.rb +7 -7
  45. data/lib/jsi/schema/validation/not.rb +1 -1
  46. data/lib/jsi/schema/validation/numeric.rb +5 -5
  47. data/lib/jsi/schema/validation/object.rb +2 -2
  48. data/lib/jsi/schema/validation/pattern.rb +2 -2
  49. data/lib/jsi/schema/validation/properties.rb +7 -7
  50. data/lib/jsi/schema/validation/property_names.rb +1 -1
  51. data/lib/jsi/schema/validation/ref.rb +2 -2
  52. data/lib/jsi/schema/validation/required.rb +1 -1
  53. data/lib/jsi/schema/validation/someof.rb +3 -3
  54. data/lib/jsi/schema/validation/string.rb +2 -2
  55. data/lib/jsi/schema/validation/type.rb +1 -1
  56. data/lib/jsi/schema/validation.rb +1 -3
  57. data/lib/jsi/schema.rb +443 -226
  58. data/lib/jsi/schema_classes.rb +241 -147
  59. data/lib/jsi/schema_registry.rb +78 -19
  60. data/lib/jsi/schema_set.rb +114 -28
  61. data/lib/jsi/simple_wrap.rb +18 -4
  62. data/lib/jsi/util/private/attr_struct.rb +141 -0
  63. data/lib/jsi/util/private/memo_map.rb +75 -0
  64. data/lib/jsi/util/private.rb +185 -0
  65. data/lib/jsi/{typelike_modules.rb → util/typelike.rb} +79 -105
  66. data/lib/jsi/util.rb +157 -153
  67. data/lib/jsi/validation/error.rb +4 -0
  68. data/lib/jsi/validation/result.rb +18 -32
  69. data/lib/jsi/version.rb +1 -1
  70. data/lib/jsi.rb +65 -39
  71. data/lib/schemas/json-schema.org/draft-04/schema.rb +160 -3
  72. data/lib/schemas/json-schema.org/draft-06/schema.rb +162 -3
  73. data/lib/schemas/json-schema.org/draft-07/schema.rb +189 -3
  74. metadata +27 -11
  75. data/lib/jsi/metaschema.rb +0 -7
  76. data/lib/jsi/pathed_node.rb +0 -116
  77. data/lib/jsi/schema/validation/core.rb +0 -39
  78. data/lib/jsi/util/attr_struct.rb +0 -106
@@ -1,30 +1,45 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JSI
4
- # JSI::Schema::Ref is a reference to another schema (the result of #deref_schema), resolved using a ref URI
5
- # from a ref schema (the ref URI typically the contents of the ref_schema's "$ref" keyword)
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] a reference URI
8
- # @param ref_schema [JSI::Schema] a schema from which the reference originated
9
- def initialize(ref, ref_schema = nil)
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 = Addressable::URI.parse(ref)
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 instance_variable_defined?(:@deref_schema)
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?(MetaschemaNode::BootstrapSchema) ? nil : ref_schema.schema_resource_root
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
- schema_resource_root = JSI.schema_registry.find(ref_abs_uri)
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'].each_key do |k|
73
- if Addressable::URI.parse(ref_schema.jsi_document['schemas'][k]['id']) == ref_uri_nofrag
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) { ptr.evaluate(schema_resource_root) }
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
- %Q(\#<#{self.class.name} #{ref}>)
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
- # @private
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
- include Util::FingerprintHash
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
- # this may be the absolute schema URI of a parent schema or the URI from which the document was retrieved.
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
- def jsi_schema_resource_ancestors
18
- return @jsi_schema_resource_ancestors if instance_variable_defined?(:@jsi_schema_resource_ancestors)
19
- [].freeze
20
- end
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
- # if this node is a schema with an id, this is its absolute URI; otherwise a parent resource's URI,
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
- if is_a?(Schema) && schema_absolute_uri
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
- # a schema at or below this node with the given anchor.
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 = jsi_anchor_subschemas_map[anchor]
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 [Array<JSI::Schema>]
59
+ # @return [Set<JSI::Schema>]
50
60
  def jsi_anchor_subschemas(anchor)
51
- jsi_anchor_subschemas_map[anchor]
61
+ @anchor_subschemas_map[anchor: anchor]
52
62
  end
53
63
 
54
64
  private
55
65
 
56
- def jsi_document=(jsi_document)
57
- @jsi_document = jsi_document
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
- unless jsi_schema_base_uri.respond_to?(:to_str)
70
- raise(TypeError, "jsi_schema_base_uri must be string or Addressable::URI; got: #{jsi_schema_base_uri.inspect}")
71
- end
72
- @jsi_schema_base_uri = Addressable::URI.parse(jsi_schema_base_uri).freeze
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
- if jsi_schema_resource_ancestors
83
- unless jsi_schema_resource_ancestors.respond_to?(:to_ary)
84
- raise(TypeError, "jsi_schema_resource_ancestors must be an array; got: #{jsi_schema_resource_ancestors.inspect}")
85
- end
86
- jsi_schema_resource_ancestors.each { |a| Schema.ensure_schema(a) }
87
- # sanity check the ancestors are in order
88
- last_anc_ptr = nil
89
- jsi_schema_resource_ancestors.each do |anc|
90
- if last_anc_ptr.nil?
91
- # pass
92
- elsif last_anc_ptr == anc.jsi_ptr
93
- raise(Bug, "duplicate ancestors in #{jsi_schema_resource_ancestors.pretty_inspect}")
94
- elsif !last_anc_ptr.contains?(anc.jsi_ptr)
95
- raise(Bug, "ancestor ptr #{anc.jsi_ptr} not contained by previous: #{last_anc_ptr} in #{jsi_schema_resource_ancestors.pretty_inspect}")
96
- end
97
- if anc.jsi_ptr == jsi_ptr
98
- raise(Bug, "ancestor is self")
99
- elsif !anc.jsi_ptr.contains?(jsi_ptr)
100
- raise(Bug, "ancestor does not contain self")
101
- end
102
- last_anc_ptr = anc.jsi_ptr
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
- def jsi_anchor_subschemas_map
112
- jsi_memomap(__method__) do |anchor|
113
- jsi_each_child_node.select do |node|
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
- end
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 schema_content.key?('maxItems')
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 schema_content.key?('minItems')
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 schema_content.key?('uniqueItems')
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 schema_content.key?('const')
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 schema_content.key?('contains')
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'], [i])
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 schema_content.key?('dependencies')
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 schema_content.key?('exclusiveMaximum')
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
- if !schema_content.key?('maximum')
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 schema_content.key?('maximum')
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 schema_content.key?('exclusiveMinimum')
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
- if !schema_content.key?('minimum')
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 schema_content.key?('minimum')
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,8 +4,6 @@ module JSI
4
4
  module Schema::Validation::Draft04
5
5
  autoload :MinMax, 'jsi/schema/validation/draft04/minmax'
6
6
 
7
- include Schema::Validation::Core
8
-
9
7
  include Schema::Validation::Ref
10
8
 
11
9
  include Schema::Validation::MultipleOf
@@ -2,8 +2,6 @@
2
2
 
3
3
  module JSI
4
4
  module Schema::Validation::Draft06
5
- include Schema::Validation::Core
6
-
7
5
  include Schema::Validation::Ref
8
6
  include Schema::Validation::AllOf
9
7
  include Schema::Validation::AnyOf
@@ -2,8 +2,6 @@
2
2
 
3
3
  module JSI
4
4
  module Schema::Validation::Draft07
5
- include Schema::Validation::Core
6
-
7
5
  include Schema::Validation::Ref
8
6
 
9
7
  include Schema::Validation::Type
@@ -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 schema_content.key?('enum')
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 schema_content.key?('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 schema_content.key?('then')
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 schema_content.key?('else')
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 schema_content.key?('then')
37
+ if keyword?('then')
38
38
  result_builder.schema_warning('`then` has no effect without adjacent `if` keyword', 'then')
39
39
  end
40
- if schema_content.key?('else')
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 schema_content.key?('items')
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], [i])
18
- elsif schema_content.key?('additionalItems')
19
- results[i] = result_builder.child_subschema_validate(['additionalItems'], [i])
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'], [i])
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 schema_content.key?('additionalItems')
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 schema_content.key?('additionalItems')
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 schema_content.key?('not')
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 schema_content.key?('multipleOf')
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 schema_content.key?('maximum')
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 schema_content.key?('exclusiveMaximum')
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 schema_content.key?('minimum')
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 schema_content.key?('exclusiveMinimum')
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 schema_content.key?('maxProperties')
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 schema_content.key?('minProperties')
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 schema_content.key?('pattern')
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