json-schema 1.0.5 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
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