json_schemer 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f44b977f6f07e9dfbb34d58681bc0b22059143bc761364b8c8edb81b5ba7fb16
4
- data.tar.gz: f606d14d205b33bb4f1c221cb6526e79afee01d965d61883763c8f516fabd69e
3
+ metadata.gz: a8a7a9d5181f0da2becb05779a587291aaa9fdcdf1ce2eeb2745165f860ff4c4
4
+ data.tar.gz: a287a3ce5b40ad941b114e4c95c4ad613c3372b3aa30549078ce998b9405c913
5
5
  SHA512:
6
- metadata.gz: 046d14ee062722084b3b7954c488b6e86ba89b5ba112879b53ecf173c3c969d183ec4baa381c2f30eca61f6595fbe199337cff5ecfbb4eb7226d1f662d4b80e9
7
- data.tar.gz: 684807637dc7510c868fc173716a1846c35368db792bd8fa1a8e2de605d3e58901df668b451567610294bd989ea057a6fb28e02bd59c2bd4d1df0b4f7571d629
6
+ metadata.gz: cb6bb847b36e285d969c160462d0a42d3fb0ba1cce7f479f13b6bfe759df299591f86bb05d1f6a6e545a96508c27fb1cb48e828ec431e07c3b8036392dbc20c0
7
+ data.tar.gz: 53a14606a501034d0693f54e2dd56706a573d950c26fddc9950effcc9dbc4762eaf929756b1d609a9e7bf0c0a5507dd8913e5c6078fbf0ff5b68eae7b851a6e9
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- json_schemer (0.1.1)
4
+ json_schemer (0.1.2)
5
5
  ecma-re-validator (~> 0.1.2)
6
6
  hana (~> 1.3.3)
7
7
  uri_template (~> 0.7.0)
data/README.md CHANGED
@@ -24,15 +24,47 @@ Or install it yourself as:
24
24
  require 'json_schemer'
25
25
 
26
26
  schema = {
27
- 'type' => 'integer'
27
+ 'type' => 'object',
28
+ 'properties' => {
29
+ 'abc' => {
30
+ 'type' => 'integer',
31
+ 'minimum' => 11
32
+ }
33
+ }
28
34
  }
29
35
  schemer = JSONSchemer::Schema.new(schema)
30
36
 
31
- schemer.valid?(1)
37
+ # true/false validation
38
+
39
+ schemer.valid?({ 'abc' => 11 })
32
40
  # => true
33
41
 
34
- schemer.valid?(1.1)
42
+ schemer.valid?({ 'abc' => 10 })
35
43
  # => false
44
+
45
+ # error validation (`validate` returns an enumerator)
46
+
47
+ schemer.validate({ 'abc' => 10 }).to_a
48
+ # => [{"data"=>10, "schema"=>{"type"=>"integer", "minimum"=>11}, "pointer"=>"#/abc", "type"=>"minimum"}]
49
+ ```
50
+
51
+ ## Options
52
+
53
+ ```ruby
54
+ JSONSchemer::Schema.new(
55
+ schema,
56
+
57
+ # validate `format` (https://tools.ietf.org/html/draft-handrews-json-schema-validation-00#section-7)
58
+ # true/false
59
+ # default: true
60
+ format: true,
61
+
62
+ # resolve external references
63
+ # 'net/http'/proc/lambda/respond_to?(:call)
64
+ # 'net/http': proc { |uri| JSON.parse(Net::HTTP.get(uri)) }
65
+ # default: proc { |uri| raise UnknownRef, uri.to_s }
66
+ ref_resolver: 'net/http'
67
+ )
36
68
  ```
37
69
 
38
70
  ## Development
@@ -15,17 +15,29 @@ require "uri_template"
15
15
 
16
16
  module JSONSchemer
17
17
  class Schema
18
+ class InvalidMetaSchema < StandardError; end
19
+ class UnknownRef < StandardError; end
20
+
21
+ META_SCHEMA = 'http://json-schema.org/draft-07/schema#'
22
+ DEFAULT_REF_RESOLVER = proc { |uri| raise UnknownRef, uri.to_s }.freeze
23
+ NET_HTTP_REF_RESOLVER = proc { |uri| JSON.parse(Net::HTTP.get(uri)) }.freeze
18
24
  BOOLEANS = Set[true, false].freeze
19
25
 
20
- def initialize(schema)
26
+ def initialize(schema, format: true, ref_resolver: DEFAULT_REF_RESOLVER)
27
+ if schema.is_a?(Hash) && schema.key?('$schema') && schema['$schema'] != META_SCHEMA
28
+ raise InvalidMetaSchema, "draft-07 is the only supported meta-schema (#{META_SCHEMA})"
29
+ end
30
+
21
31
  @root = schema
32
+ @format = format
33
+ @ref_resolver = ref_resolver == 'net/http' ? NET_HTTP_REF_RESOLVER : ref_resolver
22
34
  end
23
35
 
24
- def valid?(data, schema = root, pointer = '#', parent_uri = nil)
36
+ def valid?(data, schema = root, pointer = '', parent_uri = nil)
25
37
  validate(data, schema, pointer, parent_uri).none?
26
38
  end
27
39
 
28
- def validate(data, schema = root, pointer = '#', parent_uri = nil)
40
+ def validate(data, schema = root, pointer = '', parent_uri = nil)
29
41
  return enum_for(:validate, data, schema, pointer, parent_uri) unless block_given?
30
42
 
31
43
  return if schema == true
@@ -45,6 +57,7 @@ module JSONSchemer
45
57
  if_schema = schema['if']
46
58
  then_schema = schema['then']
47
59
  else_schema = schema['else']
60
+ format = schema['format']
48
61
  ref = schema['$ref']
49
62
  id = schema['$id']
50
63
 
@@ -55,6 +68,8 @@ module JSONSchemer
55
68
  return
56
69
  end
57
70
 
71
+ validate_format(data, schema, pointer, format, &Proc.new) if format && format?
72
+
58
73
  yield error(data, schema, pointer, 'enum') if enum && !enum.include?(data)
59
74
  yield error(data, schema, pointer, 'const') if schema.key?('const') && schema['const'] != data
60
75
 
@@ -91,7 +106,11 @@ module JSONSchemer
91
106
 
92
107
  private
93
108
 
94
- attr_reader :root
109
+ attr_reader :root, :ref_resolver
110
+
111
+ def format?
112
+ !!@format
113
+ end
95
114
 
96
115
  def error(data, schema, pointer, type)
97
116
  {
@@ -144,19 +163,59 @@ module JSONSchemer
144
163
  if ref.start_with?('#')
145
164
  validate(data, ref_pointer.eval(root), pointer, pointer_uri(root, ref_pointer), &Proc.new)
146
165
  else
147
- ref_root = JSON.parse(Net::HTTP.get(ref_uri))
166
+ ref_root = ref_resolver.call(ref_uri)
148
167
  ref_object = self.class.new(ref_root)
149
168
  ref_object.validate(data, ref_pointer.eval(ref_root), pointer, pointer_uri(ref_root, ref_pointer), &Proc.new)
150
169
  end
151
170
  elsif ids.key?(ref_uri.to_s)
152
171
  validate(data, ids.fetch(ref_uri.to_s), pointer, ref_uri, &Proc.new)
153
172
  else
154
- ref_root = JSON.parse(Net::HTTP.get(ref_uri))
173
+ ref_root = ref_resolver.call(ref_uri)
155
174
  ref_object = self.class.new(ref_root)
156
175
  ref_object.validate(data, ref_object.ids.fetch(ref_uri.to_s, ref_root), pointer, ref_uri, &Proc.new)
157
176
  end
158
177
  end
159
178
 
179
+ def validate_format(data, schema, pointer, format)
180
+ valid = case format
181
+ when 'date-time'
182
+ valid_date_time?(data)
183
+ when 'date'
184
+ valid_date_time?("#{data}T04:05:06.123456789+07:00")
185
+ when 'time'
186
+ valid_date_time?("2001-02-03T#{data}")
187
+ when 'email'
188
+ data.ascii_only? && valid_email?(data)
189
+ when 'idn-email'
190
+ valid_email?(data)
191
+ when 'hostname'
192
+ data.ascii_only? && valid_hostname?(data)
193
+ when 'idn-hostname'
194
+ valid_hostname?(data)
195
+ when 'ipv4'
196
+ valid_ip?(data, :v4)
197
+ when 'ipv6'
198
+ valid_ip?(data, :v6)
199
+ when 'uri'
200
+ data.ascii_only? && valid_iri?(data)
201
+ when 'uri-reference'
202
+ data.ascii_only? && (valid_iri?(data) || valid_iri_reference?(data))
203
+ when 'iri'
204
+ valid_iri?(data)
205
+ when 'iri-reference'
206
+ valid_iri?(data) || valid_iri_reference?(data)
207
+ when 'uri-template'
208
+ valid_uri_template?(data)
209
+ when 'json-pointer'
210
+ valid_json_pointer?(data)
211
+ when 'relative-json-pointer'
212
+ valid_relative_json_pointer?(data)
213
+ when 'regex'
214
+ EcmaReValidator.valid?(data)
215
+ end
216
+ yield error(data, schema, pointer, 'format') unless valid
217
+ end
218
+
160
219
  def validate_numeric(data, schema, pointer)
161
220
  multiple_of = schema['multipleOf']
162
221
  maximum = schema['maximum']
@@ -202,7 +261,6 @@ module JSONSchemer
202
261
  max_length = schema['maxLength']
203
262
  min_length = schema['minLength']
204
263
  pattern = schema['pattern']
205
- format = schema['format']
206
264
  content_encoding = schema['contentEncoding']
207
265
  content_media_type = schema['contentMediaType']
208
266
 
@@ -210,8 +268,6 @@ module JSONSchemer
210
268
  yield error(data, schema, pointer, 'minLength') if min_length && data.size < min_length
211
269
  yield error(data, schema, pointer, 'pattern') if pattern && Regexp.new(pattern) !~ data
212
270
 
213
- validate_string_format(data, schema, pointer, format, &Proc.new) if format
214
-
215
271
  if content_encoding || content_media_type
216
272
  decoded_data = data
217
273
 
@@ -236,46 +292,6 @@ module JSONSchemer
236
292
  end
237
293
  end
238
294
 
239
- def validate_string_format(data, schema, pointer, format)
240
- valid = case format
241
- when 'date-time'
242
- valid_date_time?(data)
243
- when 'date'
244
- valid_date_time?("#{data}T04:05:06.123456789+07:00")
245
- when 'time'
246
- valid_date_time?("2001-02-03T#{data}")
247
- when 'email'
248
- data.ascii_only? && valid_email?(data)
249
- when 'idn-email'
250
- valid_email?(data)
251
- when 'hostname'
252
- data.ascii_only? && valid_hostname?(data)
253
- when 'idn-hostname'
254
- valid_hostname?(data)
255
- when 'ipv4'
256
- valid_ip?(data, :v4)
257
- when 'ipv6'
258
- valid_ip?(data, :v6)
259
- when 'uri'
260
- data.ascii_only? && valid_iri?(data)
261
- when 'uri-reference'
262
- data.ascii_only? && (valid_iri?(data) || valid_iri_reference?(data))
263
- when 'iri'
264
- valid_iri?(data)
265
- when 'iri-reference'
266
- valid_iri?(data) || valid_iri_reference?(data)
267
- when 'uri-template'
268
- valid_uri_template?(data)
269
- when 'json-pointer'
270
- valid_json_pointer?(data)
271
- when 'relative-json-pointer'
272
- valid_relative_json_pointer?(data)
273
- when 'regex'
274
- EcmaReValidator.valid?(data)
275
- end
276
- yield error(data, schema, pointer, 'format') unless valid
277
- end
278
-
279
295
  def validate_array(data, schema, pointer, parent_uri, &block)
280
296
  unless data.is_a?(Array)
281
297
  yield error(data, schema, pointer, 'array')
@@ -1,3 +1,3 @@
1
1
  module JSONSchemer
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json_schemer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Harsha
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-01-24 00:00:00.000000000 Z
11
+ date: 2018-01-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler