json-schema 1.0.5 → 1.0.6

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.
data/README.textile CHANGED
@@ -18,7 +18,7 @@ From the git repo:
18
18
 
19
19
  <pre>
20
20
  $ gem build json-schema.gemspec
21
- $ gem install json-schema-1.0.5.gem
21
+ $ gem install json-schema-1.0.6.gem
22
22
  </pre>
23
23
 
24
24
 
data/lib/json-schema.rb CHANGED
@@ -11,7 +11,7 @@ if begin
11
11
 
12
12
  # Force MultiJson to load an engine before we define the JSON constant here; otherwise,
13
13
  # it looks for things that are under the JSON namespace that aren't there (since we have defined it here)
14
- MultiJson.engine
14
+ MultiJson.respond_to?(:adapter) ? MultiJson.adapter : MultiJson.engine
15
15
  end
16
16
 
17
17
  $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/json-schema"
@@ -21,4 +21,4 @@ require 'schema'
21
21
  require 'validator'
22
22
  Dir[File.join(File.dirname(__FILE__), "json-schema/attributes/*.rb")].each {|file| require file }
23
23
  Dir[File.join(File.dirname(__FILE__), "json-schema/validators/*.rb")].each {|file| require file }
24
- require 'uri/file'
24
+ require 'uri/file'
@@ -4,12 +4,12 @@ module JSON
4
4
  def self.validate(current_schema, data, fragments, validator, options = {})
5
5
  case current_schema.schema['format']
6
6
 
7
- # Timestamp in restricted ISO-8601 YYYY-MM-DDThh:mm:ssZ
7
+ # Timestamp in restricted ISO-8601 YYYY-MM-DDThh:mm:ssZ with optional decimal fraction of the second
8
8
  when 'date-time'
9
9
  if data.is_a?(String)
10
- error_message = "The property '#{build_fragment(fragments)}' must be a date/time in the ISO-8601 format of YYYY-MM-DDThh:mm:ssZ"
10
+ error_message = "The property '#{build_fragment(fragments)}' must be a date/time in the ISO-8601 format of YYYY-MM-DDThh:mm:ssZ or YYYY-MM-DDThh:mm:ss.ssZ"
11
11
  validation_error(error_message, fragments, current_schema, self, options[:record_errors]) and return if !data.is_a?(String)
12
- r = Regexp.new('^\d\d\d\d-\d\d-\d\dT(\d\d):(\d\d):(\d\d)Z$')
12
+ r = Regexp.new('^\d\d\d\d-\d\d-\d\dT(\d\d):(\d\d):(\d\d)([\.,]\d+)?Z$')
13
13
  if (m = r.match(data))
14
14
  parts = data.split("T")
15
15
  begin
@@ -296,6 +296,14 @@ module JSON
296
296
  end
297
297
  end
298
298
 
299
+ def validate_json(schema, data, opts={})
300
+ validate(schema, data, opts.merge(:json => true))
301
+ end
302
+
303
+ def validate_uri(schema, data, opts={})
304
+ validate(schema, data, opts.merge(:uri => true))
305
+ end
306
+
299
307
  def validate!(schema, data,opts={})
300
308
  validator = JSON::Validator.new(schema, data, opts)
301
309
  validator.validate
@@ -303,6 +311,13 @@ module JSON
303
311
  end
304
312
  alias_method 'validate2', 'validate!'
305
313
 
314
+ def validate_json!(schema, data, opts={})
315
+ validate!(schema, data, opts.merge(:json => true))
316
+ end
317
+
318
+ def validate_uri!(schema, data, opts={})
319
+ validate!(schema, data, opts.merge(:uri => true))
320
+ end
306
321
 
307
322
  def fully_validate(schema, data, opts={})
308
323
  opts[:record_errors] = true
@@ -316,6 +331,13 @@ module JSON
316
331
  fully_validate(schema, data, opts)
317
332
  end
318
333
 
334
+ def fully_validate_json(schema, data, opts={})
335
+ fully_validate(schema, data, opts.merge(:json => true))
336
+ end
337
+
338
+ def fully_validate_uri(schema, data, opts={})
339
+ fully_validate(schema, data, opts.merge(:uri => true))
340
+ end
319
341
 
320
342
  def clear_cache
321
343
  @@schemas = {} if @@cache_schemas == false
@@ -363,7 +385,7 @@ module JSON
363
385
 
364
386
  def json_backend
365
387
  if defined?(MultiJson)
366
- MultiJson.engine
388
+ MultiJson.respond_to?(:adapter) ? MultiJson.adapter : MultiJson.engine
367
389
  else
368
390
  @@json_backend
369
391
  end
@@ -372,7 +394,7 @@ module JSON
372
394
  def json_backend=(backend)
373
395
  if defined?(MultiJson)
374
396
  backend = backend == 'json' ? 'json_gem' : backend
375
- MultiJson.engine = backend
397
+ MultiJson.respond_to?(:use) ? MultiJson.use(backend) : MultiJson.engine = backend
376
398
  else
377
399
  backend = backend.to_s
378
400
  if @@available_json_backends.include?(backend)
@@ -385,7 +407,7 @@ module JSON
385
407
 
386
408
  def parse(s)
387
409
  if defined?(MultiJson)
388
- MultiJson.decode(s)
410
+ MultiJson.respond_to?(:load) ? MultiJson.load(s) : MultiJson.decode(s)
389
411
  else
390
412
  case @@json_backend.to_s
391
413
  when 'json'
@@ -451,7 +473,7 @@ module JSON
451
473
 
452
474
  def serialize schema
453
475
  if defined?(MultiJson)
454
- MultiJson.encode(schema)
476
+ MultiJson.respond_to?(:dump) ? MultiJson.dump(schema) : MultiJson.encode(schema)
455
477
  else
456
478
  @@serializer.call(schema)
457
479
  end
@@ -510,20 +532,35 @@ module JSON
510
532
 
511
533
 
512
534
  def initialize_data(data)
513
- # Parse the data, if any
514
- if data.is_a?(String)
535
+ if @options[:json]
536
+ data = JSON::Validator.parse(data)
537
+ elsif @options[:uri]
538
+ json_uri = URI.parse(data)
539
+ if json_uri.relative?
540
+ if data[0,1] == '/'
541
+ json_uri = URI.parse("file://#{data}")
542
+ else
543
+ json_uri = URI.parse("file://#{Dir.pwd}/#{data}")
544
+ end
545
+ end
546
+ data = JSON::Validator.parse(open(json_uri.to_s).read)
547
+ elsif data.is_a?(String)
515
548
  begin
516
549
  data = JSON::Validator.parse(data)
517
550
  rescue
518
- json_uri = URI.parse(data)
519
- if json_uri.relative?
520
- if data[0,1] == '/'
521
- schema_uri = URI.parse("file://#{data}")
522
- else
523
- schema_uri = URI.parse("file://#{Dir.pwd}/#{data}")
551
+ begin
552
+ json_uri = URI.parse(data)
553
+ if json_uri.relative?
554
+ if data[0,1] == '/'
555
+ json_uri = URI.parse("file://#{data}")
556
+ else
557
+ json_uri = URI.parse("file://#{Dir.pwd}/#{data}")
558
+ end
524
559
  end
560
+ data = JSON::Validator.parse(open(json_uri.to_s).read)
561
+ rescue
562
+ # Silently discard the error - the data will not change
525
563
  end
526
- data = JSON::Validator.parse(open(json_uri.to_s).read)
527
564
  end
528
565
  end
529
566
  data
data/test/test_files.rb CHANGED
@@ -16,13 +16,21 @@ class JSONSchemaTest < Test::Unit::TestCase
16
16
 
17
17
  def test_data_from_file
18
18
  schema = {"type" => "object", "properties" => {"a" => {"type" => "integer"}}}
19
- assert(JSON::Validator.validate(schema,File.join(File.dirname(__FILE__),"data/good_data_1.json")))
20
- assert(!JSON::Validator.validate(schema,File.join(File.dirname(__FILE__),"data/bad_data_1.json")))
19
+ assert(JSON::Validator.validate_uri(schema,File.join(File.dirname(__FILE__),"data/good_data_1.json")))
20
+ assert(!JSON::Validator.validate_uri(schema,File.join(File.dirname(__FILE__),"data/bad_data_1.json")))
21
+ end
22
+
23
+ def test_data_from_json
24
+ if JSON::Validator.json_backend != nil
25
+ schema = {"type" => "object", "properties" => {"a" => {"type" => "integer"}}}
26
+ assert(JSON::Validator.validate_json(schema, %Q({"a" : 5})))
27
+ assert(!JSON::Validator.validate_json(schema, %Q({"a" : "poop"})))
28
+ end
21
29
  end
22
30
 
23
31
  def test_both_from_file
24
- assert(JSON::Validator.validate(File.join(File.dirname(__FILE__),"schemas/good_schema_1.json"),File.join(File.dirname(__FILE__),"data/good_data_1.json")))
25
- assert(!JSON::Validator.validate(File.join(File.dirname(__FILE__),"schemas/good_schema_1.json"),File.join(File.dirname(__FILE__),"data/bad_data_1.json")))
32
+ assert(JSON::Validator.validate_uri(File.join(File.dirname(__FILE__),"schemas/good_schema_1.json"),File.join(File.dirname(__FILE__),"data/good_data_1.json")))
33
+ assert(!JSON::Validator.validate_uri(File.join(File.dirname(__FILE__),"schemas/good_schema_1.json"),File.join(File.dirname(__FILE__),"data/bad_data_1.json")))
26
34
  end
27
35
 
28
36
  def test_file_ref
@@ -145,4 +145,65 @@ class JSONFullValidation < Test::Unit::TestCase
145
145
  assert(errors[1][:failed_attribute] == "Type")
146
146
  assert(errors[1][:fragment] == "#/c")
147
147
  end
148
+
149
+ def test_full_validation_with_nested_required_properties
150
+ schema = {
151
+ "$schema" => "http://json-schema.org/draft-03/schema#",
152
+ "type" => "object",
153
+ "properties" => {
154
+ "x" => {
155
+ "required" => true,
156
+ "type" => "object",
157
+ "properties" => {
158
+ "a" => {"type"=>"integer","required"=>true},
159
+ "b" => {"type"=>"integer","required"=>true},
160
+ "c" => {"type"=>"integer","required"=>false},
161
+ "d" => {"type"=>"integer","required"=>false},
162
+ "e" => {"type"=>"integer","required"=>false},
163
+ }
164
+ }
165
+ }
166
+ }
167
+ data = {"x" => {"a"=>5, "d"=>5, "e"=>"what?"}}
168
+
169
+ errors = JSON::Validator.fully_validate(schema,data,:errors_as_objects => true)
170
+ assert_equal 2, errors.length
171
+ assert_equal '#/x', errors[0][:fragment]
172
+ assert_equal 'Properties', errors[0][:failed_attribute]
173
+ assert_equal '#/x/e', errors[1][:fragment]
174
+ assert_equal 'Type', errors[1][:failed_attribute]
175
+ end
176
+
177
+ def test_full_validation_with_nested_required_propertiesin_array
178
+ schema = {
179
+ "$schema" => "http://json-schema.org/draft-03/schema#",
180
+ "type" => "object",
181
+ "properties" => {
182
+ "x" => {
183
+ "required" => true,
184
+ "type" => "array",
185
+ "items" => {
186
+ "type" => "object",
187
+ "properties" => {
188
+ "a" => {"type"=>"integer","required"=>true},
189
+ "b" => {"type"=>"integer","required"=>true},
190
+ "c" => {"type"=>"integer","required"=>false},
191
+ "d" => {"type"=>"integer","required"=>false},
192
+ "e" => {"type"=>"integer","required"=>false},
193
+ }
194
+ }
195
+ }
196
+ }
197
+ }
198
+ missing_b= {"a"=>5}
199
+ e_is_wrong_type= {"a"=>5,"b"=>5,"e"=>"what?"}
200
+ data = {"x" => [missing_b, e_is_wrong_type]}
201
+
202
+ errors = JSON::Validator.fully_validate(schema,data,:errors_as_objects => true)
203
+ assert_equal 2, errors.length
204
+ assert_equal '#/x/0', errors[0][:fragment]
205
+ assert_equal 'Properties', errors[0][:failed_attribute]
206
+ assert_equal '#/x/1/e', errors[1][:fragment]
207
+ assert_equal 'Type', errors[1][:failed_attribute]
208
+ end
148
209
  end
@@ -28,6 +28,8 @@ class JSONSchemaDraft3Test < Test::Unit::TestCase
28
28
  data['a'] = true
29
29
  assert(!JSON::Validator.validate(schema,data))
30
30
 
31
+ assert(JSON::Validator.validate({'type' => 'integer'}, 3))
32
+ assert(!JSON::Validator.validate({'type' => 'integer'}, "hello"))
31
33
 
32
34
  # Test numbers
33
35
  schema["properties"]["a"]["type"] = "number"
@@ -43,6 +45,10 @@ class JSONSchemaDraft3Test < Test::Unit::TestCase
43
45
  data['a'] = true
44
46
  assert(!JSON::Validator.validate(schema,data))
45
47
 
48
+ assert(JSON::Validator.validate({'type' => 'number'}, 3))
49
+ assert(JSON::Validator.validate({'type' => 'number'}, 3.14159265358979))
50
+ assert(!JSON::Validator.validate({'type' => 'number'}, "hello"))
51
+
46
52
 
47
53
  # Test strings
48
54
  schema["properties"]["a"]["type"] = "string"
@@ -58,6 +64,10 @@ class JSONSchemaDraft3Test < Test::Unit::TestCase
58
64
  data['a'] = true
59
65
  assert(!JSON::Validator.validate(schema,data))
60
66
 
67
+ assert(JSON::Validator.validate({'type' => 'string'}, 'hello'))
68
+ assert(!JSON::Validator.validate({'type' => 'string'}, 3.14159265358979))
69
+ assert(!JSON::Validator.validate({'type' => 'string'}, []))
70
+
61
71
 
62
72
  # Test booleans
63
73
  schema["properties"]["a"]["type"] = "boolean"
@@ -76,6 +86,12 @@ class JSONSchemaDraft3Test < Test::Unit::TestCase
76
86
  data['a'] = false
77
87
  assert(JSON::Validator.validate(schema,data))
78
88
 
89
+ assert(JSON::Validator.validate({'type' => 'boolean'}, true))
90
+ assert(JSON::Validator.validate({'type' => 'boolean'}, false))
91
+ assert(!JSON::Validator.validate({'type' => 'boolean'}, nil))
92
+ assert(!JSON::Validator.validate({'type' => 'boolean'}, 3))
93
+ assert(!JSON::Validator.validate({'type' => 'boolean'}, "hello"))
94
+
79
95
 
80
96
  # Test object
81
97
  schema["properties"]["a"]["type"] = "object"
@@ -91,6 +107,12 @@ class JSONSchemaDraft3Test < Test::Unit::TestCase
91
107
  data['a'] = true
92
108
  assert(!JSON::Validator.validate(schema,data))
93
109
 
110
+ assert(JSON::Validator.validate({'type' => 'objec'}, {'a' => true}))
111
+ assert(JSON::Validator.validate({'type' => 'object'}, {}))
112
+ assert(!JSON::Validator.validate({'type' => 'object'}, []))
113
+ assert(!JSON::Validator.validate({'type' => 'object'}, 3))
114
+ assert(!JSON::Validator.validate({'type' => 'object'}, "hello"))
115
+
94
116
 
95
117
  # Test array
96
118
  schema["properties"]["a"]["type"] = "array"
@@ -106,6 +128,12 @@ class JSONSchemaDraft3Test < Test::Unit::TestCase
106
128
  data['a'] = true
107
129
  assert(!JSON::Validator.validate(schema,data))
108
130
 
131
+ assert(JSON::Validator.validate({'type' => 'array'}, ['a']))
132
+ assert(JSON::Validator.validate({'type' => 'array'}, []))
133
+ assert(!JSON::Validator.validate({'type' => 'array'}, {}))
134
+ assert(!JSON::Validator.validate({'type' => 'array'}, 3))
135
+ assert(!JSON::Validator.validate({'type' => 'array'}, "hello"))
136
+
109
137
 
110
138
  # Test null
111
139
  schema["properties"]["a"]["type"] = "null"
@@ -121,6 +149,11 @@ class JSONSchemaDraft3Test < Test::Unit::TestCase
121
149
  data['a'] = true
122
150
  assert(!JSON::Validator.validate(schema,data))
123
151
 
152
+ assert(JSON::Validator.validate({'type' => 'null'}, nil))
153
+ assert(!JSON::Validator.validate({'type' => 'null'}, false))
154
+ assert(!JSON::Validator.validate({'type' => 'null'}, []))
155
+ assert(!JSON::Validator.validate({'type' => 'null'}, "hello"))
156
+
124
157
 
125
158
  # Test any
126
159
  schema["properties"]["a"]["type"] = "any"
@@ -136,6 +169,12 @@ class JSONSchemaDraft3Test < Test::Unit::TestCase
136
169
  data['a'] = true
137
170
  assert(JSON::Validator.validate(schema,data))
138
171
 
172
+ assert(JSON::Validator.validate({'type' => 'any'}, true))
173
+ assert(JSON::Validator.validate({'type' => 'any'}, nil))
174
+ assert(JSON::Validator.validate({'type' => 'any'}, {}))
175
+ assert(JSON::Validator.validate({'type' => 'any'}, 3))
176
+ assert(JSON::Validator.validate({'type' => 'any'}, "hello"))
177
+
139
178
 
140
179
  # Test a union type
141
180
  schema["properties"]["a"]["type"] = ["integer","string"]
@@ -148,6 +187,9 @@ class JSONSchemaDraft3Test < Test::Unit::TestCase
148
187
  data["a"] = false
149
188
  assert(!JSON::Validator.validate(schema,data))
150
189
 
190
+ assert(JSON::Validator.validate({'type' => ['string', 'null']}, "hello"))
191
+ assert(!JSON::Validator.validate({'type' => ['integer', 'object']}, "hello"))
192
+
151
193
  # Test a union type with schemas
152
194
  schema["properties"]["a"]["type"] = [{ "type" => "string" }, {"type" => "object", "properties" => {"b" => {"type" => "integer"}}}]
153
195
 
@@ -883,6 +925,10 @@ class JSONSchemaDraft3Test < Test::Unit::TestCase
883
925
 
884
926
  data = {"a" => "2010-01-01T12:00:00Z"}
885
927
  assert(JSON::Validator.validate(schema,data))
928
+ data = {"a" => "2010-01-01T12:00:00.1Z"}
929
+ assert(JSON::Validator.validate(schema,data))
930
+ data = {"a" => "2010-01-01T12:00:00,1Z"}
931
+ assert(JSON::Validator.validate(schema,data))
886
932
  data = {"a" => "2010-01-32T12:00:00Z"}
887
933
  assert(!JSON::Validator.validate(schema,data))
888
934
  data = {"a" => "2010-13-01T12:00:00Z"}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json-schema
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 1.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-21 00:00:00.000000000 Z
12
+ date: 2012-05-29 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description:
15
15
  email: hoxworth@gmail.com