jddf 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +9 -4
- data/lib/jddf.rb +1 -1
- data/lib/jddf/schema.rb +65 -6
- data/lib/jddf/validator.rb +49 -3
- data/lib/jddf/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c72fdc3f849585ccb396ce421b3a786ac80b82e6bd655687663f990324422f65
|
4
|
+
data.tar.gz: 4569216d22965df94997de1934c3e978b558f566607d62e6175102871f1338a5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6bc424c05db14b6a242b7d4d0c1e407f1fb20b5667724eaff7c97c9f971f07a0aa332c85faa7badc7bbe28fdbb72897eaf0d9cbdde950a331341cfe1c0d11fff
|
7
|
+
data.tar.gz: df9ec4d23c0d91075a386482063b0bc22a1d6722e33b790603a9788d67141aac45d64142b1d0b8bcdcb706a6a2b679dbd30a5b64a523979d8b2b3a67b55a8135
|
data/Gemfile.lock
CHANGED
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
|
35
|
-
* `Validator
|
36
|
-
|
37
|
-
|
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
|
|
data/lib/jddf.rb
CHANGED
data/lib/jddf/schema.rb
CHANGED
@@ -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
|
-
|
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)
|
data/lib/jddf/validator.rb
CHANGED
@@ -3,17 +3,29 @@
|
|
3
3
|
require 'time'
|
4
4
|
|
5
5
|
module JDDF
|
6
|
-
#
|
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
|
-
#
|
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
|
data/lib/jddf/version.rb
CHANGED
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.
|
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-
|
11
|
+
date: 2019-11-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|