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.
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