jtd 0.1.2 → 0.1.3
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/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:
|