json-schema 2.6.1 → 2.7.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.
- checksums.yaml +4 -4
- data/README.md +168 -241
- data/lib/json-schema/attributes/additionalitems.rb +1 -1
- data/lib/json-schema/attributes/additionalproperties.rb +1 -1
- data/lib/json-schema/attributes/extends.rb +0 -2
- data/lib/json-schema/attributes/items.rb +1 -0
- data/lib/json-schema/attributes/ref.rb +2 -2
- data/lib/json-schema/schema/reader.rb +33 -5
- data/lib/json-schema/util/uri.rb +5 -1
- data/lib/json-schema/validator.rb +17 -18
- metadata +7 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f440a3f87c238f6b4a3ba8fb93818ae17affd9fc
|
|
4
|
+
data.tar.gz: 910c2401bf9e11a0d57dfe8e47086c876e7e48b4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dbf3e34a23275021b9cf6f9d9ccb5aa86956182411f55e93fa3cd29b30d24b01d18c30e191cb31dd5a1c71b780188b08cb261d7248e203bcfa74d9b1f104f273
|
|
7
|
+
data.tar.gz: a5311ed16954806392eabe157ccd92d9b54b3e20e228697c31bc0042f1455c0b7e4bff6a2b33db473a93116020fdcf9a6296e621cb55638287103142e54c3839
|
data/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
](https://travis-ci.org/ruby-json-schema/json-schema)
|
|
2
|
+
[](https://codeclimate.com/github/ruby-json-schema/json-schema)
|
|
3
3
|
|
|
4
4
|
Ruby JSON Schema Validator
|
|
5
5
|
==========================
|
|
@@ -42,10 +42,10 @@ $ gem build json-schema.gemspec
|
|
|
42
42
|
$ gem install json-schema-2.5.2.gem
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
Validation
|
|
46
46
|
-----
|
|
47
47
|
|
|
48
|
-
Three base validation methods exist:
|
|
48
|
+
Three base validation methods exist:
|
|
49
49
|
|
|
50
50
|
1. `validate`: returns a boolean on whether a validation attempt passes
|
|
51
51
|
2. `validate!`: throws a `JSON::Schema::ValidationError` with an appropriate message/trace on where the validation failed
|
|
@@ -67,15 +67,15 @@ attribute in the schema and referencing the appropriate specification URI. Note
|
|
|
67
67
|
that the `$schema` attribute takes precedence over the `:version` option during
|
|
68
68
|
parsing and validation.
|
|
69
69
|
|
|
70
|
-
### Validate Ruby objects against a Ruby schema
|
|
71
|
-
|
|
72
70
|
For further information on json schema itself refer to <a
|
|
73
71
|
href="http://spacetelescope.github.io/understanding-json-schema/">Understanding
|
|
74
72
|
JSON Schema</a>.
|
|
75
73
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
74
|
+
Basic Usage
|
|
75
|
+
--------------
|
|
76
|
+
|
|
77
|
+
```ruby
|
|
78
|
+
require "json-schema"
|
|
79
79
|
|
|
80
80
|
schema = {
|
|
81
81
|
"type" => "object",
|
|
@@ -85,279 +85,206 @@ schema = {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
JSON::Validator.validate(schema, data)
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
### Validate a JSON string against a JSON schema file
|
|
96
|
-
|
|
97
|
-
```rb
|
|
98
|
-
require 'rubygems'
|
|
99
|
-
require 'json-schema'
|
|
100
|
-
|
|
101
|
-
JSON::Validator.validate('schema.json', '{"a" : 5}')
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
### Validate a list of objects against a schema that represents the individual objects
|
|
105
|
-
|
|
106
|
-
```rb
|
|
107
|
-
require 'rubygems'
|
|
108
|
-
require 'json-schema'
|
|
109
|
-
|
|
110
|
-
data = ['user','user','user']
|
|
111
|
-
JSON::Validator.validate('user.json', data, :list => true)
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
### Strictly validate an object's properties
|
|
115
|
-
|
|
116
|
-
With the `:strict` option, validation fails when an object contains properties
|
|
117
|
-
that are not defined in the schema's property list or doesn't match the
|
|
118
|
-
`additionalProperties` property. Furthermore, all properties are treated as
|
|
119
|
-
`required` regardless of `required` properties set in the schema.
|
|
88
|
+
#
|
|
89
|
+
# validate ruby objects against a ruby schema
|
|
90
|
+
#
|
|
120
91
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
92
|
+
# => true
|
|
93
|
+
JSON::Validator.validate(schema, { "a" => 5 })
|
|
94
|
+
# => false
|
|
95
|
+
JSON::Validator.validate(schema, {})
|
|
124
96
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
"a" => {"type" => "integer"},
|
|
129
|
-
"b" => {"type" => "integer"}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
97
|
+
#
|
|
98
|
+
# validate a json string against a json schema file
|
|
99
|
+
#
|
|
132
100
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
JSON::Validator.validate(schema, {"a" => 1}, :strict => true) # ==> false
|
|
136
|
-
```
|
|
101
|
+
require "json"
|
|
102
|
+
File.write("schema.json", JSON.dump(schema))
|
|
137
103
|
|
|
138
|
-
|
|
104
|
+
# => true
|
|
105
|
+
JSON::Validator.validate('schema.json', '{ "a": 5 }')
|
|
139
106
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
schema = {
|
|
145
|
-
"type" => "object",
|
|
146
|
-
"required" => ["a"],
|
|
147
|
-
"properties" => {
|
|
148
|
-
"a" => {"type" => "integer"}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
data = {
|
|
153
|
-
"a" => "taco"
|
|
154
|
-
}
|
|
107
|
+
#
|
|
108
|
+
# raise an error when validation fails
|
|
109
|
+
#
|
|
155
110
|
|
|
111
|
+
# => "The property '#/a' of type String did not match the following type: integer"
|
|
156
112
|
begin
|
|
157
|
-
JSON::Validator.validate!(schema,
|
|
158
|
-
rescue JSON::Schema::ValidationError
|
|
159
|
-
|
|
113
|
+
JSON::Validator.validate!(schema, { "a" => "taco" })
|
|
114
|
+
rescue JSON::Schema::ValidationError => e
|
|
115
|
+
e.message
|
|
160
116
|
end
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### Fully validate against a schema and catch all errors
|
|
164
|
-
|
|
165
|
-
```rb
|
|
166
|
-
require 'rubygems'
|
|
167
|
-
require 'json-schema'
|
|
168
|
-
|
|
169
|
-
schema = {
|
|
170
|
-
"type" => "object",
|
|
171
|
-
"required" => ["a","b"],
|
|
172
|
-
"properties" => {
|
|
173
|
-
"a" => {"type" => "integer"},
|
|
174
|
-
"b" => {"type" => "string"}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
data = {
|
|
179
|
-
"a" => "taco"
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
errors = JSON::Validator.fully_validate(schema, data)
|
|
183
|
-
|
|
184
|
-
# ["The property '#/a' of type String did not match the following type: integer in schema 03179a21-197e-5414-9611-e9f63e8324cd#", "The property '#/' did not contain a required property of 'b' in schema 03179a21-197e-5414-9611-e9f63e8324cd#"]
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
### Fully validate against a schema and catch all errors as objects
|
|
188
|
-
|
|
189
|
-
```rb
|
|
190
|
-
require 'rubygems'
|
|
191
|
-
require 'json-schema'
|
|
192
|
-
|
|
193
|
-
schema = {
|
|
194
|
-
"type" => "object",
|
|
195
|
-
"required" => ["a","b"],
|
|
196
|
-
"properties" => {
|
|
197
|
-
"a" => {"type" => "integer"},
|
|
198
|
-
"b" => {"type" => "string"}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
data = {
|
|
203
|
-
"a" => "taco"
|
|
204
|
-
}
|
|
205
117
|
|
|
206
|
-
|
|
118
|
+
#
|
|
119
|
+
# return an array of error messages when validation fails
|
|
120
|
+
#
|
|
207
121
|
|
|
208
|
-
# [
|
|
122
|
+
# => ["The property '#/a' of type String did not match the following type: integer in schema 18a1ffbb-4681-5b00-bd15-2c76aee4b28f"]
|
|
123
|
+
JSON::Validator.fully_validate(schema, { "a" => "taco" })
|
|
209
124
|
```
|
|
210
125
|
|
|
211
|
-
|
|
126
|
+
Advanced Options
|
|
127
|
+
-----------------
|
|
212
128
|
|
|
213
|
-
```
|
|
214
|
-
require
|
|
215
|
-
require 'json-schema'
|
|
129
|
+
```ruby
|
|
130
|
+
require "json-schema"
|
|
216
131
|
|
|
217
132
|
schema = {
|
|
218
|
-
"type"
|
|
219
|
-
"required" => ["a"
|
|
133
|
+
"type"=>"object",
|
|
134
|
+
"required" => ["a"],
|
|
220
135
|
"properties" => {
|
|
221
|
-
"a" => {
|
|
222
|
-
|
|
223
|
-
|
|
136
|
+
"a" => {
|
|
137
|
+
"type" => "integer",
|
|
138
|
+
"default" => 42
|
|
139
|
+
},
|
|
140
|
+
"b" => {
|
|
224
141
|
"type" => "object",
|
|
225
142
|
"properties" => {
|
|
226
|
-
"
|
|
143
|
+
"x" => {
|
|
144
|
+
"type" => "integer"
|
|
145
|
+
}
|
|
227
146
|
}
|
|
228
147
|
}
|
|
229
148
|
}
|
|
230
149
|
}
|
|
231
150
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
schema
|
|
151
|
+
#
|
|
152
|
+
# with the `:list` option, a list can be validated against a schema that represents the individual objects
|
|
153
|
+
#
|
|
154
|
+
|
|
155
|
+
# => true
|
|
156
|
+
JSON::Validator.validate(schema, [{"a" => 1}, {"a" => 2}, {"a" => 3}], :list => true)
|
|
157
|
+
# => false
|
|
158
|
+
JSON::Validator.validate(schema, [{"a" => 1}, {"a" => 2}, {"a" => 3}])
|
|
159
|
+
|
|
160
|
+
#
|
|
161
|
+
# with the `:errors_as_objects` option, `#fully_validate` returns errors as hashes instead of strings
|
|
162
|
+
#
|
|
163
|
+
|
|
164
|
+
# => [{:schema=>#<Addressable::URI:0x3ffa69cbeed8 URI:18a1ffbb-4681-5b00-bd15-2c76aee4b28f>, :fragment=>"#/a", :message=>"The property '#/a' of type String did not match the following type: integer in schema 18a1ffbb-4681-5b00-bd15-2c76aee4b28f", :failed_attribute=>"TypeV4"}]
|
|
165
|
+
JSON::Validator.fully_validate(schema, { "a" => "taco" }, :errors_as_objects => true)
|
|
166
|
+
|
|
167
|
+
#
|
|
168
|
+
# with the `:strict` option, all properties are condisidered to have `"required": true` and all objects `"additionalProperties": false`
|
|
169
|
+
#
|
|
170
|
+
|
|
171
|
+
# => true
|
|
172
|
+
JSON::Validator.validate(schema, { "a" => 1, "b" => { "x" => 2 } }, :strict => true)
|
|
173
|
+
# => false
|
|
174
|
+
JSON::Validator.validate(schema, { "a" => 1, "b" => { "x" => 2 }, "c" => 3 }, :strict => true)
|
|
175
|
+
# => false
|
|
176
|
+
JSON::Validator.validate(schema, { "a" => 1 }, :strict => true)
|
|
177
|
+
|
|
178
|
+
#
|
|
179
|
+
# with the `:fragment` option, only a fragment of the schema is used for validation
|
|
180
|
+
#
|
|
181
|
+
|
|
182
|
+
# => true
|
|
183
|
+
JSON::Validator.validate(schema, { "x" => 1 }, :fragment => "#/properties/b")
|
|
184
|
+
# => false
|
|
185
|
+
JSON::Validator.validate(schema, { "x" => 1 })
|
|
186
|
+
|
|
187
|
+
#
|
|
188
|
+
# with the `:validate_schema` option, the schema is validated (against the json schema spec) before the json is validated (against the specified schema)
|
|
189
|
+
#
|
|
190
|
+
|
|
191
|
+
# => true
|
|
192
|
+
JSON::Validator.validate(schema, { "a" => 1 }, :validate_schema => true)
|
|
193
|
+
# => false
|
|
194
|
+
JSON::Validator.validate({ "required" => true }, { "a" => 1 }, :validate_schema => true)
|
|
195
|
+
|
|
196
|
+
#
|
|
197
|
+
# with the `:insert_defaults` option, any undefined values in the json that have a default in the schema are replaced with the default before validation
|
|
198
|
+
#
|
|
199
|
+
|
|
200
|
+
# => true
|
|
201
|
+
JSON::Validator.validate(schema, {}, :insert_defaults => true)
|
|
202
|
+
# => false
|
|
203
|
+
JSON::Validator.validate(schema, {})
|
|
204
|
+
|
|
205
|
+
#
|
|
206
|
+
# with the `:version` option, schemas conforming to older drafts of the json schema spec can be used
|
|
207
|
+
#
|
|
208
|
+
|
|
209
|
+
v2_schema = {
|
|
246
210
|
"type" => "object",
|
|
247
|
-
"required" => ["a"],
|
|
248
211
|
"properties" => {
|
|
249
|
-
"a" => {
|
|
250
|
-
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
data = {
|
|
254
|
-
"a" => 5
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
JSON::Validator.validate(schema, data, :validate_schema => true)
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
### Validate a JSON object against a JSON schema object, while inserting default values from the schema
|
|
261
|
-
|
|
262
|
-
With the `:insert_defaults` option set to true any missing property that has a
|
|
263
|
-
default value specified in the schema will be inserted into the validated data.
|
|
264
|
-
The inserted default value is validated hence catching a schema that specifies
|
|
265
|
-
an invalid default value.
|
|
266
|
-
|
|
267
|
-
```rb
|
|
268
|
-
require 'rubygems'
|
|
269
|
-
require 'json-schema'
|
|
270
|
-
|
|
271
|
-
schema = {
|
|
272
|
-
"type" => "object",
|
|
273
|
-
"required" => ["a"],
|
|
274
|
-
"properties" => {
|
|
275
|
-
"a" => {"type" => "integer", "default" => 42},
|
|
276
|
-
"b" => {"type" => "integer"}
|
|
212
|
+
"a" => {
|
|
213
|
+
"type" => "integer"
|
|
214
|
+
}
|
|
277
215
|
}
|
|
278
216
|
}
|
|
279
217
|
|
|
280
|
-
#
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
}
|
|
218
|
+
# => false
|
|
219
|
+
JSON::Validator.validate(v2_schema, {}, :version => :draft2)
|
|
220
|
+
# => true
|
|
221
|
+
JSON::Validator.validate(v2_schema, {})
|
|
285
222
|
|
|
286
|
-
|
|
287
|
-
# false
|
|
288
|
-
|
|
289
|
-
JSON::Validator.validate(schema, data, :insert_defaults => true)
|
|
290
|
-
# true
|
|
291
|
-
# data = {
|
|
292
|
-
# "a" => 42,
|
|
293
|
-
# "b" => 5
|
|
294
|
-
# }
|
|
295
|
-
```
|
|
223
|
+
#
|
|
224
|
+
# with the `:parse_data` option set to false, the json must be a parsed ruby object (not a json text, a uri or a file path)
|
|
225
|
+
#
|
|
296
226
|
|
|
297
|
-
|
|
227
|
+
# => true
|
|
228
|
+
JSON::Validator.validate(schema, { "a" => 1 }, :parse_data => false)
|
|
229
|
+
# => false
|
|
230
|
+
JSON::Validator.validate(schema, '{ "a": 1 }', :parse_data => false)
|
|
298
231
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
232
|
+
#
|
|
233
|
+
# with the `:json` option, the json must be an unparsed json text (not a hash, a uri or a file path)
|
|
234
|
+
#
|
|
302
235
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
"a" => 5
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
JSON::Validator.validate(schema, data, :version => :draft2)
|
|
315
|
-
```
|
|
236
|
+
# => true
|
|
237
|
+
JSON::Validator.validate(schema, '{ "a": 1 }', :json => true)
|
|
238
|
+
# => "no implicit conversion of Hash into String"
|
|
239
|
+
begin
|
|
240
|
+
JSON::Validator.validate(schema, { "a" => 1 }, :json => true)
|
|
241
|
+
rescue TypeError => e
|
|
242
|
+
e.message
|
|
243
|
+
end
|
|
316
244
|
|
|
317
|
-
|
|
245
|
+
#
|
|
246
|
+
# with the `:uri` option, the json must be a uri or file path (not a hash or a json text)
|
|
247
|
+
#
|
|
318
248
|
|
|
319
|
-
|
|
320
|
-
parameter, and it will try to work out what to do with it dynamically. You can
|
|
321
|
-
pass it a string uri (in which case it will download the json from that location
|
|
322
|
-
before validating), a string of JSON text, or simply a ruby object (such as an
|
|
323
|
-
array or hash representing parsed json). However, sometimes the nature of the
|
|
324
|
-
data is ambiguous (for example, is "http://github.com" just a string, or is it a
|
|
325
|
-
uri?). In other situations, you have already parsed your JSON, and you don't
|
|
326
|
-
need to re-parse it.
|
|
249
|
+
File.write("data.json", '{ "a": 1 }')
|
|
327
250
|
|
|
328
|
-
|
|
329
|
-
|
|
251
|
+
# => true
|
|
252
|
+
JSON::Validator.validate(schema, "data.json", :uri => true)
|
|
253
|
+
# => "Can't convert Hash into String."
|
|
254
|
+
begin
|
|
255
|
+
JSON::Validator.validate(schema, { "a" => 1 }, :uri => true)
|
|
256
|
+
rescue TypeError => e
|
|
257
|
+
e.message
|
|
258
|
+
end
|
|
330
259
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
260
|
+
#
|
|
261
|
+
# with the `:clear_cache` option set to true, the internal cache of schemas is
|
|
262
|
+
# cleared after validation (otherwise schemas are cached for efficiency)
|
|
263
|
+
#
|
|
334
264
|
|
|
335
|
-
schema
|
|
336
|
-
"type" => "string"
|
|
337
|
-
}
|
|
265
|
+
File.write("schema.json", v2_schema.to_json)
|
|
338
266
|
|
|
339
|
-
#
|
|
340
|
-
JSON::Validator.validate(schema,
|
|
267
|
+
# => true
|
|
268
|
+
JSON::Validator.validate("schema.json", {})
|
|
341
269
|
|
|
342
|
-
|
|
343
|
-
JSON::Validator.validate(schema, 'https://api.github.com', :parse_data => false) # returns true
|
|
270
|
+
File.write("schema.json", schema.to_json)
|
|
344
271
|
|
|
345
|
-
#
|
|
346
|
-
JSON::Validator.validate(schema
|
|
272
|
+
# => true
|
|
273
|
+
JSON::Validator.validate("schema.json", {}, :clear_cache => true)
|
|
347
274
|
|
|
348
|
-
#
|
|
349
|
-
JSON::Validator.validate(schema
|
|
275
|
+
# => false
|
|
276
|
+
JSON::Validator.validate("schema.json", {})
|
|
350
277
|
```
|
|
351
278
|
|
|
352
|
-
|
|
279
|
+
Extending Schemas
|
|
280
|
+
-----------------
|
|
353
281
|
|
|
354
282
|
For this example, we are going to extend the [JSON Schema Draft
|
|
355
283
|
3](http://tools.ietf.org/html/draft-zyp-json-schema-03) specification by adding
|
|
356
284
|
a 'bitwise-and' property for validation.
|
|
357
285
|
|
|
358
|
-
```
|
|
359
|
-
require
|
|
360
|
-
require 'json-schema'
|
|
286
|
+
```ruby
|
|
287
|
+
require "json-schema"
|
|
361
288
|
|
|
362
289
|
class BitwiseAndAttribute < JSON::Schema::Attribute
|
|
363
290
|
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
|
@@ -403,7 +330,8 @@ data = {"a" => 0, "b" => "taco"}
|
|
|
403
330
|
JSON::Validator.validate(schema,data) # => false
|
|
404
331
|
```
|
|
405
332
|
|
|
406
|
-
|
|
333
|
+
Custom format validation
|
|
334
|
+
------------------------
|
|
407
335
|
|
|
408
336
|
The JSON schema standard allows custom formats in schema definitions which
|
|
409
337
|
should be ignored by validators that do not support them. JSON::Schema allows
|
|
@@ -412,9 +340,8 @@ checked as parameter and must raise a `JSON::Schema::CustomFormatError` to
|
|
|
412
340
|
indicate a format violation. The error message will be prepended by the property
|
|
413
341
|
name, e.g. [The property '#a']()
|
|
414
342
|
|
|
415
|
-
```
|
|
416
|
-
require
|
|
417
|
-
require 'json-schema'
|
|
343
|
+
```ruby
|
|
344
|
+
require "json-schema"
|
|
418
345
|
|
|
419
346
|
format_proc = -> value {
|
|
420
347
|
raise JSON::Schema::CustomFormatError.new("must be 42") unless value == "42"
|
|
@@ -456,7 +383,7 @@ control all schemas which should be used by validation, this could be
|
|
|
456
383
|
accomplished by registering all referenced schemas with the validator in
|
|
457
384
|
advance:
|
|
458
385
|
|
|
459
|
-
```
|
|
386
|
+
```ruby
|
|
460
387
|
schema = JSON::Schema.new(some_schema_definition, Addressable::URI.parse('http://example.com/my-schema'))
|
|
461
388
|
JSON::Validator.add_schema(schema)
|
|
462
389
|
```
|
|
@@ -464,7 +391,7 @@ JSON::Validator.add_schema(schema)
|
|
|
464
391
|
If more extensive control is necessary, the `JSON::Schema::Reader` instance used
|
|
465
392
|
can be configured in a few ways:
|
|
466
393
|
|
|
467
|
-
```
|
|
394
|
+
```ruby
|
|
468
395
|
# Change the default schema reader used
|
|
469
396
|
JSON::Validator.schema_reader = JSON::Schema::Reader.new(:accept_uri => true, :accept_file => false)
|
|
470
397
|
|
|
@@ -491,7 +418,7 @@ If more than one of the supported JSON backends are installed, the `yajl-ruby`
|
|
|
491
418
|
parser is used by default. This can be changed by issuing the following before
|
|
492
419
|
validation:
|
|
493
420
|
|
|
494
|
-
```
|
|
421
|
+
```ruby
|
|
495
422
|
JSON::Validator.json_backend = :json
|
|
496
423
|
```
|
|
497
424
|
|
|
@@ -11,7 +11,7 @@ module JSON
|
|
|
11
11
|
|
|
12
12
|
case schema['additionalItems']
|
|
13
13
|
when false
|
|
14
|
-
if schema['items'].length
|
|
14
|
+
if schema['items'].length < data.length
|
|
15
15
|
message = "The property '#{build_fragment(fragments)}' contains additional array elements outside of the schema when none are allowed"
|
|
16
16
|
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
|
|
17
17
|
end
|
|
@@ -14,7 +14,7 @@ module JSON
|
|
|
14
14
|
if addprop.is_a?(Hash)
|
|
15
15
|
matching_properties = extra_properties # & addprop.keys
|
|
16
16
|
matching_properties.each do |key|
|
|
17
|
-
additional_property_schema = JSON::Schema.new(addprop
|
|
17
|
+
additional_property_schema = JSON::Schema.new(addprop, current_schema.uri, validator)
|
|
18
18
|
additional_property_schema.validate(data[key], fragments + [key], processor, options)
|
|
19
19
|
end
|
|
20
20
|
extra_properties -= matching_properties
|
|
@@ -48,11 +48,11 @@ module JSON
|
|
|
48
48
|
if ref_schema
|
|
49
49
|
# Perform fragment resolution to retrieve the appropriate level for the schema
|
|
50
50
|
target_schema = ref_schema.schema
|
|
51
|
-
fragments = temp_uri.fragment.split("/")
|
|
51
|
+
fragments = JSON::Util::URI.parse(JSON::Util::URI.unescape_uri(temp_uri)).fragment.split("/")
|
|
52
52
|
fragment_path = ''
|
|
53
53
|
fragments.each do |fragment|
|
|
54
54
|
if fragment && fragment != ''
|
|
55
|
-
fragment =
|
|
55
|
+
fragment = fragment.gsub('~0', '~').gsub('~1', '/')
|
|
56
56
|
if target_schema.is_a?(Array)
|
|
57
57
|
target_schema = target_schema[fragment.to_i]
|
|
58
58
|
else
|
|
@@ -3,9 +3,8 @@ require 'pathname'
|
|
|
3
3
|
|
|
4
4
|
module JSON
|
|
5
5
|
class Schema
|
|
6
|
-
#
|
|
7
|
-
|
|
8
|
-
class ReadRefused < StandardError
|
|
6
|
+
# Base for any reading exceptions encountered by {JSON::Schema::Reader}
|
|
7
|
+
class ReadError < StandardError
|
|
9
8
|
# @return [String] the requested schema location which was refused
|
|
10
9
|
attr_reader :location
|
|
11
10
|
|
|
@@ -15,7 +14,30 @@ module JSON
|
|
|
15
14
|
def initialize(location, type)
|
|
16
15
|
@location = location
|
|
17
16
|
@type = type
|
|
18
|
-
super(
|
|
17
|
+
super(error_message)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def type_string
|
|
23
|
+
type == :uri ? 'URI' : type.to_s
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Raised by {JSON::Schema::Reader} when one of its settings indicate
|
|
28
|
+
# a schema should not be read.
|
|
29
|
+
class ReadRefused < ReadError
|
|
30
|
+
private
|
|
31
|
+
def error_message
|
|
32
|
+
"Read of #{type_string} at #{location} refused"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Raised by {JSON::Schema::Reader} when an attempt to read a schema fails
|
|
37
|
+
class ReadFailed < ReadError
|
|
38
|
+
private
|
|
39
|
+
def error_message
|
|
40
|
+
"Read of #{type_string} at #{location} failed"
|
|
19
41
|
end
|
|
20
42
|
end
|
|
21
43
|
|
|
@@ -58,6 +80,8 @@ module JSON
|
|
|
58
80
|
# @raise [JSON::Schema::ReadRefused] if +accept_uri+ or +accept_file+
|
|
59
81
|
# indicated the schema could not be read
|
|
60
82
|
# @raise [JSON::Schema::ParseError] if the schema was not a valid JSON object
|
|
83
|
+
# @raise [JSON::Schema::ReadFailed] if reading the location was acceptable but the
|
|
84
|
+
# attempt to retrieve it failed
|
|
61
85
|
def read(location)
|
|
62
86
|
uri = JSON::Util::URI.parse(location.to_s)
|
|
63
87
|
body = if uri.scheme.nil? || uri.scheme == 'file'
|
|
@@ -98,14 +122,18 @@ module JSON
|
|
|
98
122
|
else
|
|
99
123
|
raise JSON::Schema::ReadRefused.new(uri.to_s, :uri)
|
|
100
124
|
end
|
|
125
|
+
rescue OpenURI::HTTPError, SocketError
|
|
126
|
+
raise JSON::Schema::ReadFailed.new(uri.to_s, :uri)
|
|
101
127
|
end
|
|
102
128
|
|
|
103
129
|
def read_file(pathname)
|
|
104
130
|
if accept_file?(pathname)
|
|
105
|
-
File.read(JSON::Util::URI.
|
|
131
|
+
File.read(JSON::Util::URI.unescaped_path(pathname.to_s))
|
|
106
132
|
else
|
|
107
133
|
raise JSON::Schema::ReadRefused.new(pathname.to_s, :file)
|
|
108
134
|
end
|
|
135
|
+
rescue Errno::ENOENT
|
|
136
|
+
raise JSON::Schema::ReadFailed.new(pathname.to_s, :file)
|
|
109
137
|
end
|
|
110
138
|
end
|
|
111
139
|
end
|
data/lib/json-schema/util/uri.rb
CHANGED
|
@@ -54,7 +54,11 @@ module JSON
|
|
|
54
54
|
Addressable::URI.convert_path(parsed_uri.path)
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
-
def self.
|
|
57
|
+
def self.unescape_uri(uri)
|
|
58
|
+
Addressable::URI.unescape(uri)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def self.unescaped_path(uri)
|
|
58
62
|
parsed_uri = parse(uri)
|
|
59
63
|
|
|
60
64
|
Addressable::URI.unescape(parsed_uri.path)
|
|
@@ -18,7 +18,7 @@ module JSON
|
|
|
18
18
|
class Validator
|
|
19
19
|
|
|
20
20
|
@@schemas = {}
|
|
21
|
-
@@cache_schemas =
|
|
21
|
+
@@cache_schemas = true
|
|
22
22
|
@@default_opts = {
|
|
23
23
|
:list => false,
|
|
24
24
|
:version => nil,
|
|
@@ -26,7 +26,7 @@ module JSON
|
|
|
26
26
|
:record_errors => false,
|
|
27
27
|
:errors_as_objects => false,
|
|
28
28
|
:insert_defaults => false,
|
|
29
|
-
:clear_cache =>
|
|
29
|
+
:clear_cache => false,
|
|
30
30
|
:strict => false,
|
|
31
31
|
:parse_data => true
|
|
32
32
|
}
|
|
@@ -48,7 +48,7 @@ module JSON
|
|
|
48
48
|
@validation_options = @options[:record_errors] ? {:record_errors => true} : {}
|
|
49
49
|
@validation_options[:insert_defaults] = true if @options[:insert_defaults]
|
|
50
50
|
@validation_options[:strict] = true if @options[:strict] == true
|
|
51
|
-
@validation_options[:clear_cache] =
|
|
51
|
+
@validation_options[:clear_cache] = true if !@@cache_schemas || @options[:clear_cache]
|
|
52
52
|
|
|
53
53
|
@@mutex.synchronize { @base_schema = initialize_schema(schema_data) }
|
|
54
54
|
@original_data = data
|
|
@@ -62,8 +62,7 @@ module JSON
|
|
|
62
62
|
end
|
|
63
63
|
metaschema = base_validator ? base_validator.metaschema : validator.metaschema
|
|
64
64
|
# Don't clear the cache during metaschema validation!
|
|
65
|
-
|
|
66
|
-
meta_validator.validate
|
|
65
|
+
self.class.validate!(metaschema, @base_schema.schema, {:clear_cache => false})
|
|
67
66
|
end
|
|
68
67
|
|
|
69
68
|
# If the :fragment option is set, try and validate against the fragment
|
|
@@ -110,12 +109,17 @@ module JSON
|
|
|
110
109
|
end
|
|
111
110
|
|
|
112
111
|
# Run a simple true/false validation of data against a schema
|
|
113
|
-
def validate
|
|
112
|
+
def validate
|
|
114
113
|
@base_schema.validate(@data,[],self,@validation_options)
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
|
|
115
|
+
if @options[:record_errors]
|
|
116
|
+
if @options[:errors_as_objects]
|
|
117
|
+
@errors.map{|e| e.to_hash}
|
|
118
|
+
else
|
|
119
|
+
@errors.map{|e| e.to_string}
|
|
120
|
+
end
|
|
117
121
|
else
|
|
118
|
-
|
|
122
|
+
true
|
|
119
123
|
end
|
|
120
124
|
ensure
|
|
121
125
|
if @validation_options[:clear_cache] == true
|
|
@@ -239,9 +243,7 @@ module JSON
|
|
|
239
243
|
class << self
|
|
240
244
|
def validate(schema, data,opts={})
|
|
241
245
|
begin
|
|
242
|
-
|
|
243
|
-
validator.validate
|
|
244
|
-
return true
|
|
246
|
+
validate!(schema, data, opts)
|
|
245
247
|
rescue JSON::Schema::ValidationError, JSON::Schema::SchemaError
|
|
246
248
|
return false
|
|
247
249
|
end
|
|
@@ -258,7 +260,6 @@ module JSON
|
|
|
258
260
|
def validate!(schema, data,opts={})
|
|
259
261
|
validator = JSON::Validator.new(schema, data, opts)
|
|
260
262
|
validator.validate
|
|
261
|
-
return true
|
|
262
263
|
end
|
|
263
264
|
alias_method 'validate2', 'validate!'
|
|
264
265
|
|
|
@@ -271,9 +272,7 @@ module JSON
|
|
|
271
272
|
end
|
|
272
273
|
|
|
273
274
|
def fully_validate(schema, data, opts={})
|
|
274
|
-
opts
|
|
275
|
-
validator = JSON::Validator.new(schema, data, opts)
|
|
276
|
-
validator.validate
|
|
275
|
+
validate!(schema, data, opts.merge(:record_errors => true))
|
|
277
276
|
end
|
|
278
277
|
|
|
279
278
|
def fully_validate_schema(schema, opts={})
|
|
@@ -299,7 +298,7 @@ module JSON
|
|
|
299
298
|
end
|
|
300
299
|
|
|
301
300
|
def clear_cache
|
|
302
|
-
@@schemas = {}
|
|
301
|
+
@@schemas = {}
|
|
303
302
|
end
|
|
304
303
|
|
|
305
304
|
def schemas
|
|
@@ -608,7 +607,7 @@ module JSON
|
|
|
608
607
|
end
|
|
609
608
|
else
|
|
610
609
|
begin
|
|
611
|
-
File.read(JSON::Util::URI.
|
|
610
|
+
File.read(JSON::Util::URI.unescaped_path(uri))
|
|
612
611
|
rescue SystemCallError => e
|
|
613
612
|
raise JSON::Schema::JsonLoadError, e.message
|
|
614
613
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: json-schema
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kenny Hoxworth
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2016-
|
|
11
|
+
date: 2016-09-29 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rake
|
|
@@ -70,16 +70,16 @@ dependencies:
|
|
|
70
70
|
name: addressable
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
72
72
|
requirements:
|
|
73
|
-
- - "
|
|
73
|
+
- - ">="
|
|
74
74
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: 2.
|
|
75
|
+
version: '2.4'
|
|
76
76
|
type: :runtime
|
|
77
77
|
prerelease: false
|
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
79
|
requirements:
|
|
80
|
-
- - "
|
|
80
|
+
- - ">="
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: 2.
|
|
82
|
+
version: '2.4'
|
|
83
83
|
description:
|
|
84
84
|
email: hoxworth@gmail.com
|
|
85
85
|
executables: []
|
|
@@ -161,7 +161,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
161
161
|
requirements:
|
|
162
162
|
- - ">="
|
|
163
163
|
- !ruby/object:Gem::Version
|
|
164
|
-
version: 1.
|
|
164
|
+
version: '1.9'
|
|
165
165
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
166
166
|
requirements:
|
|
167
167
|
- - ">="
|
|
@@ -174,4 +174,3 @@ signing_key:
|
|
|
174
174
|
specification_version: 4
|
|
175
175
|
summary: Ruby JSON Schema Validator
|
|
176
176
|
test_files: []
|
|
177
|
-
has_rdoc:
|