jddf 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b488c9c91ad6f8eed43e3295b1a7bfbce20985d3aee9217eb2c9defc5f737e8c
4
- data.tar.gz: 42676f592a08589204ccbb03aa68118714c60c10b0415a0a194cee9b65a7e228
3
+ metadata.gz: c72fdc3f849585ccb396ce421b3a786ac80b82e6bd655687663f990324422f65
4
+ data.tar.gz: 4569216d22965df94997de1934c3e978b558f566607d62e6175102871f1338a5
5
5
  SHA512:
6
- metadata.gz: c9a69812ceae8889294f9b6adc0848d14b7f66511145156af42a34fe7e9f1de5aa678b684372249d8cef6a643b48f4b7cc3c9b8a341f3d960bb449593785cf4c
7
- data.tar.gz: 0e04a88ceac3add797277390fcffed2256229abef37f68cb0515291f85096ff9475a27c6372ec9c267c90976aabef96768cc550afa81e945ebffb8e5f3cc843b
6
+ metadata.gz: 6bc424c05db14b6a242b7d4d0c1e407f1fb20b5667724eaff7c97c9f971f07a0aa332c85faa7badc7bbe28fdbb72897eaf0d9cbdde950a331341cfe1c0d11fff
7
+ data.tar.gz: df9ec4d23c0d91075a386482063b0bc22a1d6722e33b790603a9788d67141aac45d64142b1d0b8bcdcb706a6a2b679dbd30a5b64a523979d8b2b3a67b55a8135
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- jddf (0.2.0)
4
+ jddf (0.2.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -31,10 +31,15 @@ gem 'jddf'
31
31
 
32
32
  The two most important classes offered by the `JDDF` module are:
33
33
 
34
- * `Schema`, which represents a JDDF schema,
35
- * `Validator`, which can validate a `Schema` against any parsed JSON data, and
36
- * `ValidationError`, which represents a single validation problem with the
37
- input. `Validator#validate` returns an array of these.
34
+ * [`Schema`][schema], which represents a JDDF schema,
35
+ * [`Validator`][validator], which can validate a `Schema` against any parsed
36
+ JSON data, and
37
+ * [`ValidationError`][validation-error], which represents a single validation
38
+ problem with the input. `Validator#validate` returns an array of these.
39
+
40
+ [schema]: https://www.rubydoc.info/github/jddf/jddf-ruby/master/JDDF/Schema
41
+ [validator]: https://www.rubydoc.info/github/jddf/jddf-ruby/master/JDDF/Validator
42
+ [validation-error]: https://www.rubydoc.info/github/jddf/jddf-ruby/master/JDDF/ValidationError
38
43
 
39
44
  Here's a working example:
40
45
 
@@ -4,6 +4,6 @@ require 'jddf/schema'
4
4
  require 'jddf/validator'
5
5
  require 'jddf/version'
6
6
 
7
- # JDDF asdf
7
+ # Provides support for JSON Data Defintion Format ("JDDF").
8
8
  module JDDF
9
9
  end
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JDDF
4
+ # The keywords that may appear on a JDDF schema.
5
+ #
6
+ # Each of these values correspond to an attribute available on {Schema}.
4
7
  SCHEMA_KEYWORDS = %i[
5
8
  definitions
6
9
  ref
@@ -14,11 +17,18 @@ module JDDF
14
17
  discriminator
15
18
  ].freeze
16
19
 
20
+ # The keywords that may appear on a JDDF schema discriminator object.
21
+ #
22
+ # Each of these values correspond to an attribute available on
23
+ # {Discriminator}.
17
24
  DISCRIMINATOR_KEYWORDS = %i[
18
25
  tag
19
26
  mapping
20
27
  ].freeze
21
28
 
29
+ # The values the +type+ keyword may take on in a JDDF schema.
30
+ #
31
+ # The +type+ attribute of {Schema} has one of these values.
22
32
  TYPES = %i[
23
33
  boolean
24
34
  int8
@@ -33,7 +43,28 @@ module JDDF
33
43
  timestamp
34
44
  ].freeze
35
45
 
46
+ # A JDDF schema.
47
+ #
48
+ # This class is a +Struct+. Validate instances against it using
49
+ # {Validator#validate}.
50
+ #
51
+ # This class's attributes are in {SCHEMA_KEYWORDS}.
36
52
  Schema = Struct.new(*SCHEMA_KEYWORDS) do
53
+ # Construct a {Schema} from parsed JSON.
54
+ #
55
+ # This function performs type checks to ensure the data is well-typed, but
56
+ # does not perform all the checks necesary to ensure data is a correct JDDF
57
+ # schema. Using this function in combination with {verify} ensures that a
58
+ # JDDF schema is guaranteed to be correct according to the spec.
59
+ #
60
+ # +hash+ should be the result of calling +JSON#parse+.
61
+ #
62
+ # @param hash [Hash] a JSON object representing a JDDF schema
63
+ #
64
+ # @raise [ArgumentError, TypeError] if the inputted hash is not a valid
65
+ # schema
66
+ #
67
+ # @return [Schema] the parsed schema
37
68
  def self.from_json(hash)
38
69
  raise TypeError.new, 'hash must be a Hash' unless hash.is_a?(Hash)
39
70
 
@@ -133,6 +164,12 @@ module JDDF
133
164
  schema
134
165
  end
135
166
 
167
+ # Determine which of the eight forms this schema takes on.
168
+ #
169
+ # This function is well-defined only if the schema is a correct schema --
170
+ # i.e., you have called {verify} and no errors were raised.
171
+ #
172
+ # @return [Symbol] the form of the schema
136
173
  def form
137
174
  return :ref if ref
138
175
  return :type if type
@@ -145,7 +182,20 @@ module JDDF
145
182
  :empty
146
183
  end
147
184
 
148
- def verify(root = self)
185
+ # Check that the schema represents a correct JDDF schema.
186
+ #
187
+ # To make it convenient to construct and verify a schema, this function
188
+ # returns +self+ if the schema is correct.
189
+ #
190
+ # @raise [ArgumentError] if the schema is incorrect
191
+ #
192
+ # @return [Schema] self
193
+ def verify(root = self, is_root = true)
194
+ if definitions
195
+ raise ArgumentError, 'non-root definitions' unless is_root
196
+ definitions.values.each { |schema| schema.verify(root, false) }
197
+ end
198
+
149
199
  empty = true
150
200
 
151
201
  if ref
@@ -173,7 +223,7 @@ module JDDF
173
223
 
174
224
  empty = false
175
225
 
176
- elements.verify(root)
226
+ elements.verify(root, false)
177
227
  end
178
228
 
179
229
  if properties || optional_properties
@@ -181,8 +231,8 @@ module JDDF
181
231
 
182
232
  empty = false
183
233
 
184
- properties&.values&.each { |schema| schema.verify(root) }
185
- optional_properties&.values&.each { |schema| schema.verify(root) }
234
+ properties&.values&.each { |schema| schema.verify(root, false) }
235
+ optional_properties&.values&.each { |schema| schema.verify(root, false) }
186
236
  end
187
237
 
188
238
  if values
@@ -190,7 +240,7 @@ module JDDF
190
240
 
191
241
  empty = false
192
242
 
193
- values.verify(root)
243
+ values.verify(root, false)
194
244
  end
195
245
 
196
246
  if properties && optional_properties
@@ -203,7 +253,7 @@ module JDDF
203
253
  raise ArgumentError, 'invalid form' unless empty
204
254
 
205
255
  discriminator.mapping.values.each do |schema|
206
- schema.verify(root)
256
+ schema.verify(root, false)
207
257
 
208
258
  unless schema.form == :properties
209
259
  raise ArgumentError, 'mapping value not of properties form'
@@ -220,7 +270,16 @@ module JDDF
220
270
  end
221
271
  end
222
272
 
273
+ # A JDDF schema discriminator object.
274
+ #
275
+ # This class is a +Struct+. It is primarily a helper sub-structure of
276
+ # {Schema}.
277
+ #
278
+ # The attributes of this struct are in {DISCRIMINATOR_KEYWORDS}.
223
279
  Discriminator = Struct.new(*DISCRIMINATOR_KEYWORDS) do
280
+ # Construct a {Discriminator} from parsed JSON.
281
+ #
282
+ # This is primarily meant to be a helper method to {Schema#from_json}.
224
283
  def self.from_json(hash)
225
284
  raise TypeError, 'tag not String' unless hash['tag'].is_a?(String)
226
285
  raise TypeError, 'mapping not Hash' unless hash['mapping'].is_a?(Hash)
@@ -3,17 +3,29 @@
3
3
  require 'time'
4
4
 
5
5
  module JDDF
6
- # ValidationError
6
+ # A single JDDF validation error.
7
+ #
8
+ # Instances of this class are returned from {Validator#validate}.
9
+ #
10
+ # The attributes of this class are both arrays of strings. They represent JSON
11
+ # Pointers.
12
+ #
13
+ # @attr [Array] instance_path an array of strings pointing to the rejected
14
+ # part of the input ("instance")
15
+ #
16
+ # @attr [Array] schema_path an array of strings pointing to the part of the
17
+ # schema which rejected the instance
7
18
  ValidationError = Struct.new(:instance_path, :schema_path)
8
19
 
9
- # MaxDepthExceededError
20
+ # MaxDepthExceededError is raised when the maximum depth of a {Validator} is
21
+ # exceeded.
10
22
  class MaxDepthExceededError < StandardError
11
23
  def initialize(msg = 'max depth exceeded while validating')
12
24
  super
13
25
  end
14
26
  end
15
27
 
16
- # Validator
28
+ # Validates JSON instances against JDDF schemas.
17
29
  class Validator
18
30
  # MaxErrorsError
19
31
  class MaxErrorsError < StandardError
@@ -248,9 +260,43 @@ module JDDF
248
260
 
249
261
  private_constant :VM
250
262
 
263
+ # The maximum stack depth of references to follow when running {validate}.
264
+ #
265
+ # If this maximum depth is exceeded, such as if a schema passed to
266
+ # {validate} is defined cyclically, then {validate} throws a
267
+ # {MaxDepthExceededError}.
268
+ #
269
+ # By default, no maximum depth is enforced. The validator may overflow the
270
+ # stack if a schema is defined cyclically.
271
+ #
272
+ # @return [Integer] the maximum depth of references to follow when validating
251
273
  attr_accessor :max_depth
274
+
275
+ # The maximum number of errors to return when running {validate}.
276
+ #
277
+ # If this value is set to a number, then it's guaranteed that {validate}
278
+ # will return an array of size no greater than the value of this attribute.
279
+ #
280
+ # By default, no maximum errors is enforced. All validation errors are
281
+ # returned.
282
+ #
283
+ # @return [Integer] the maximum errors to return when validating
252
284
  attr_accessor :max_errors
253
285
 
286
+ # Validate a JDDF schema against a JSON instance.
287
+ #
288
+ # The precise rules of validation for this method are defined formally by
289
+ # the JDDF specification, and this method follows those rules exactly,
290
+ # assuming that +instance+ is the result of calling +JSON#parse+ using the
291
+ # standard library's +JSON+ module.
292
+ #
293
+ # @param schema [Schema] the schema to validate against
294
+ #
295
+ # @param instance [Object] the input ("instance") to validate
296
+ #
297
+ # @raise [MaxDepthExceededError} if {max_depth} is exceeded.
298
+ #
299
+ # @return [Array] an array of {ValidationError}
254
300
  def validate(schema, instance)
255
301
  vm = VM.new
256
302
  vm.max_depth = max_depth
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JDDF
4
- VERSION = '0.2.0'
4
+ VERSION = '0.2.1'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jddf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ulysse Carion
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-10-16 00:00:00.000000000 Z
11
+ date: 2019-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler