jtd 0.1.2 → 0.1.3
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/Gemfile.lock +1 -1
- data/lib/jtd.rb +1 -0
- data/lib/jtd/schema.rb +33 -0
- data/lib/jtd/validate.rb +75 -4
- data/lib/jtd/version.rb +2 -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: 1f3aced7e341c436f9e352366f0ac22b94ec9ee09eba6df47b02f29655615f74
|
4
|
+
data.tar.gz: 1e1c8bd6c424d1e73e91adcee30edf4bcbc833d49fb3a31fbac8b23e5901658b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 752673b1192607e90d5b22b7f9c49fec8551d6dc95533b768aef1d5bf9125d07a9aa8789fc4db2a53db97817d47b8c77e80272632cc6d370b469694e702b5ff4
|
7
|
+
data.tar.gz: 619dcb81c6b5346a14e95d3ca316e2560c409059f39adb5660a12a40d8ca5251606c83983a201fe270d8d7f89fb5be8f9ef3aea7ecbf6c1ed62918369ee1101f
|
data/Gemfile.lock
CHANGED
data/lib/jtd.rb
CHANGED
data/lib/jtd/schema.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
module JTD
|
2
|
+
# Represents a JSON Type Definition schema.
|
2
3
|
class Schema
|
3
4
|
attr_accessor *%i[
|
4
5
|
metadata
|
@@ -16,6 +17,17 @@ module JTD
|
|
16
17
|
mapping
|
17
18
|
]
|
18
19
|
|
20
|
+
# Constructs a Schema from a Hash like the kind produced by JSON#parse.
|
21
|
+
#
|
22
|
+
# In other words, #from_hash is meant to be used to convert some parsed JSON
|
23
|
+
# into a Schema.
|
24
|
+
#
|
25
|
+
# If hash isn't a Hash or contains keys that are illegal for JSON Type
|
26
|
+
# Definition, then #from_hash will raise a TypeError.
|
27
|
+
#
|
28
|
+
# If the properties of hash are not of the correct type for a JSON Type
|
29
|
+
# Definition schema (for example, if the "elements" property of hash is
|
30
|
+
# non-nil, but not a hash), then #from_hash may raise a NoMethodError.
|
19
31
|
def self.from_hash(hash)
|
20
32
|
# Raising this error early makes for a much clearer error for the
|
21
33
|
# relatively common case of something that was expected to be an object
|
@@ -74,6 +86,20 @@ module JTD
|
|
74
86
|
s
|
75
87
|
end
|
76
88
|
|
89
|
+
# Raises a TypeError or ArgumentError if the Schema is not correct according
|
90
|
+
# to the JSON Type Definition specification.
|
91
|
+
#
|
92
|
+
# See the JSON Type Definition specification for more details, but a high
|
93
|
+
# level #verify checks such things as:
|
94
|
+
#
|
95
|
+
# 1. Making sure each of the attributes of the Schema are of the right type,
|
96
|
+
# 2. The Schema uses a valid combination of JSON Type Definition keywords,
|
97
|
+
# 3. The Schema isn't ambiguous or unsatisfiable.
|
98
|
+
# 4. The Schema doesn't make references to nonexistent definitions.
|
99
|
+
#
|
100
|
+
# If root is specified, then that root is assumed to contain the schema
|
101
|
+
# being verified. By default, the Schema is considered its own root, which
|
102
|
+
# is usually the desired behavior.
|
77
103
|
def verify(root = self)
|
78
104
|
self.check_type('metadata', [Hash])
|
79
105
|
self.check_type('nullable', [TrueClass, FalseClass])
|
@@ -173,6 +199,13 @@ module JTD
|
|
173
199
|
self
|
174
200
|
end
|
175
201
|
|
202
|
+
# Returns the form that the schema takes on.
|
203
|
+
#
|
204
|
+
# The return value will be one of :empty, :ref:, :type, :enum, :elements,
|
205
|
+
# :properties, :values, or :discriminator.
|
206
|
+
#
|
207
|
+
# If the schema is not well-formed, i.e. calling #verify on it raises an
|
208
|
+
# error, then the return value of #form is not well-defined.
|
176
209
|
def form
|
177
210
|
return :ref if ref
|
178
211
|
return :type if type
|
data/lib/jtd/validate.rb
CHANGED
@@ -1,6 +1,26 @@
|
|
1
1
|
require 'time'
|
2
2
|
|
3
3
|
module JTD
|
4
|
+
# Validates +instance+ against +schema+ according to the JSON Type Definition
|
5
|
+
# specification.
|
6
|
+
#
|
7
|
+
# Returns a list of ValidationError. If there are no validation errors, then
|
8
|
+
# the returned list will be empty.
|
9
|
+
#
|
10
|
+
# By default, all errors are returned, and an unlimited number of references
|
11
|
+
# will be followed. If you are running #validate against schemas that may
|
12
|
+
# return a lot of errors, or which may contain circular references, then this
|
13
|
+
# can cause performance issues or stack overflows.
|
14
|
+
#
|
15
|
+
# To mitigate this risk, consider using +options+, which must be an instance
|
16
|
+
# of ValidationOptions, to limit the number of errors returned or references
|
17
|
+
# followed.
|
18
|
+
#
|
19
|
+
# If ValidationOptions#max_depth is reached, then #validate will raise a
|
20
|
+
# MaxDepthExceededError.
|
21
|
+
#
|
22
|
+
# The return value of #validate is not well-defined if the schema is not
|
23
|
+
# valid, i.e. Schema#verify raises an error.
|
4
24
|
def self.validate(schema, instance, options = ValidationOptions.new)
|
5
25
|
state = ValidationState.new
|
6
26
|
state.options = options
|
@@ -19,16 +39,64 @@ module JTD
|
|
19
39
|
state.errors
|
20
40
|
end
|
21
41
|
|
42
|
+
# Options you can pass to JTD::validate.
|
22
43
|
class ValidationOptions
|
23
|
-
|
24
|
-
|
44
|
+
# The maximum number of references to follow before aborting validation. You
|
45
|
+
# can use this to prevent a stack overflow when validating schemas that
|
46
|
+
# potentially have infinite loops, such as this one:
|
47
|
+
#
|
48
|
+
# {
|
49
|
+
# "definitions": {
|
50
|
+
# "loop": { "ref": "loop" }
|
51
|
+
# },
|
52
|
+
# "ref": "loop"
|
53
|
+
# }
|
54
|
+
#
|
55
|
+
# The default value for +max_depth+ is 0, which indicates that no max depth
|
56
|
+
# should be imposed at all.
|
57
|
+
attr_accessor :max_depth
|
58
|
+
|
59
|
+
# The maximum number of errors to return. You can use this to have
|
60
|
+
# JTD::validate have better performance if you don't have any use for errors
|
61
|
+
# beyond a certain count.
|
62
|
+
#
|
63
|
+
# For instance, if all you care about is whether or not there are any
|
64
|
+
# validation errors at all, you can set +max_errors+ to 1. If you're
|
65
|
+
# presenting validation errors in an interface that can't show more than 5
|
66
|
+
# errors, set +max_errors+ to 5.
|
67
|
+
#
|
68
|
+
# The default value for +max_errors+ is 0, which indicates that all errors
|
69
|
+
# will be returned.
|
70
|
+
attr_accessor :max_errors
|
71
|
+
|
72
|
+
# Construct a new set of ValidationOptions with the given +max_depth+ and
|
73
|
+
# +max_errors+.
|
74
|
+
#
|
75
|
+
# See the documentation for +max_depth+ and +max_errors+ for what their
|
76
|
+
# default values of 0 mean.
|
25
77
|
def initialize(max_depth: 0, max_errors: 0)
|
26
78
|
@max_depth = max_depth
|
27
79
|
@max_errors = max_errors
|
28
80
|
end
|
29
81
|
end
|
30
82
|
|
83
|
+
# Represents a single JSON Type Definition validation error.
|
84
|
+
#
|
85
|
+
# ValidationError does not extend StandardError; it is not a Ruby exception.
|
86
|
+
# It is a plain old Ruby object.
|
87
|
+
#
|
88
|
+
# Every ValidationError has two attributes:
|
89
|
+
#
|
90
|
+
# * +instance_path+ is an array of strings. It represents the path to the part
|
91
|
+
# of the +instance+ passed to JTD::validate that was rejected.
|
92
|
+
#
|
93
|
+
# * +schema_path+ is an array of strings. It represents the path to the part
|
94
|
+
# of the +schema+ passed to JTD::validate that rejected the instance at
|
95
|
+
# +instance_path+.
|
31
96
|
class ValidationError < Struct.new(:instance_path, :schema_path)
|
97
|
+
|
98
|
+
# Constructs a new ValidationError from the standard JSON representation of
|
99
|
+
# a validation error in JSON Type Definition.
|
32
100
|
def self.from_hash(hash)
|
33
101
|
instance_path = hash['instancePath']
|
34
102
|
schema_path = hash['schemaPath']
|
@@ -37,7 +105,10 @@ module JTD
|
|
37
105
|
end
|
38
106
|
end
|
39
107
|
|
108
|
+
# Error raised from JTD::validate if the number of references followed exceeds
|
109
|
+
# ValidationOptions#max_depth.
|
40
110
|
class MaxDepthExceededError < StandardError
|
111
|
+
# Constructs a new MaxDepthExceededError.
|
41
112
|
def initialize(msg = 'max depth exceeded during JTD::validate')
|
42
113
|
super
|
43
114
|
end
|
@@ -45,7 +116,7 @@ module JTD
|
|
45
116
|
|
46
117
|
private
|
47
118
|
|
48
|
-
class ValidationState
|
119
|
+
class ValidationState # :nodoc:
|
49
120
|
attr_accessor :options, :root_schema, :instance_tokens, :schema_tokens, :errors
|
50
121
|
|
51
122
|
def push_instance_token(token)
|
@@ -73,7 +144,7 @@ module JTD
|
|
73
144
|
|
74
145
|
private_constant :ValidationState
|
75
146
|
|
76
|
-
class MaxErrorsReachedError < StandardError
|
147
|
+
class MaxErrorsReachedError < StandardError # :nodoc:
|
77
148
|
end
|
78
149
|
|
79
150
|
private_constant :MaxErrorsReachedError
|
data/lib/jtd/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jtd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ulysse Carion
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-09-
|
11
|
+
date: 2020-09-20 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|