json-schema 1.0.8 → 1.0.9

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.
@@ -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.8.gem
21
+ $ gem install json-schema-1.0.9.gem
22
22
  </pre>
23
23
 
24
24
 
@@ -1,3 +1,5 @@
1
+ require_relative 'extends'
2
+
1
3
  module JSON
2
4
  class Schema
3
5
  class AdditionalPropertiesAttribute < Attribute
@@ -5,6 +7,28 @@ module JSON
5
7
  if data.is_a?(Hash)
6
8
  extra_properties = data.keys
7
9
 
10
+ extra_properties = remove_valid_properties(extra_properties, current_schema, validator)
11
+
12
+ addprop= current_schema.schema['additionalProperties']
13
+ if addprop.is_a?(Hash)
14
+ matching_properties= extra_properties # & addprop.keys
15
+ matching_properties.each do |key|
16
+ schema = JSON::Schema.new(addprop[key] || addprop, current_schema.uri, validator)
17
+ fragments << key
18
+ schema.validate(data[key],fragments,options)
19
+ fragments.pop
20
+ end
21
+ extra_properties -= matching_properties
22
+ end
23
+ if !extra_properties.empty? and (addprop == false or (addprop.is_a?(Hash) and !addprop.empty?))
24
+ message = "The property '#{build_fragment(fragments)}' contains additional properties #{extra_properties.inspect} outside of the schema when none are allowed"
25
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
26
+ end
27
+ end
28
+ end
29
+
30
+ def self.remove_valid_properties(extra_properties, current_schema, validator)
31
+
8
32
  if current_schema.schema['properties']
9
33
  extra_properties = extra_properties - current_schema.schema['properties'].keys
10
34
  end
@@ -21,19 +45,18 @@ module JSON
21
45
  end
22
46
  end
23
47
 
24
- if current_schema.schema['additionalProperties'] == false && !extra_properties.empty?
25
- message = "The property '#{build_fragment(fragments)}' contains additional properties #{extra_properties.inspect} outside of the schema when none are allowed"
26
- validation_error(message, fragments, current_schema, self, options[:record_errors])
27
- elsif current_schema.schema['additionalProperties'].is_a?(Hash)
28
- extra_properties.each do |key|
29
- schema = JSON::Schema.new(current_schema.schema['additionalProperties'],current_schema.uri,validator)
30
- fragments << key
31
- schema.validate(data[key],fragments,options)
32
- fragments.pop
48
+ if schemas= current_schema.schema['extends']
49
+ schemas = [schemas] if !schemas.is_a?(Array)
50
+ schemas.each do |schema_value|
51
+ temp_uri,extended_schema= JSON::Schema::ExtendsAttribute.get_extended_uri_and_schema(schema_value, current_schema, validator)
52
+ if extended_schema
53
+ extra_properties= remove_valid_properties(extra_properties, extended_schema, validator)
54
+ end
33
55
  end
34
56
  end
35
- end
57
+
58
+ extra_properties
36
59
  end
37
60
  end
38
61
  end
39
- end
62
+ end
@@ -1,3 +1,5 @@
1
+ require_relative 'ref'
2
+
1
3
  module JSON
2
4
  class Schema
3
5
  class ExtendsAttribute < Attribute
@@ -5,63 +7,43 @@ module JSON
5
7
  schemas = current_schema.schema['extends']
6
8
  schemas = [schemas] if !schemas.is_a?(Array)
7
9
  schemas.each do |s|
8
- if s.is_a?(Hash)
9
- schema = JSON::Schema.new(s,current_schema.uri,validator)
10
+ uri,schema = get_extended_uri_and_schema(s, current_schema, validator)
11
+ if schema
10
12
  schema.validate(data, fragments, options)
11
- elsif s.is_a?(String)
12
- temp_uri = URI.parse(s)
13
- if temp_uri.relative?
14
- temp_uri = current_schema.uri.clone
15
- # Check for absolute path
16
- path = s.split("#")[0]
17
- if path.nil? || path == ''
18
- temp_uri.path = current_schema.uri.path
19
- elsif path[0,1] == "/"
20
- temp_uri.path = Pathname.new(path).cleanpath.to_s
21
- else
22
- temp_uri = current_schema.uri.merge(path)
23
- end
24
- temp_uri.fragment = s.split("#")[1]
25
- end
26
- temp_uri.fragment = "" if temp_uri.fragment.nil?
13
+ elsif uri
14
+ message = "The extended schema '#{uri.to_s}' cannot be found"
15
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
16
+ else
17
+ message = "The property '#{build_fragment(fragments)}' was not a valid schema"
18
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
19
+ end
20
+ end
21
+ end
27
22
 
28
- # Grab the parent schema from the schema list
29
- schema_key = temp_uri.to_s.split("#")[0] + "#"
23
+ def self.get_extended_uri_and_schema(s, current_schema, validator)
24
+ uri,schema = nil,nil
30
25
 
31
- ref_schema = JSON::Validator.schemas[schema_key]
26
+ s = {'$ref' => s} if s.is_a?(String)
32
27
 
28
+ if s.is_a?(Hash)
29
+ uri = current_schema.uri
30
+ if s['$ref']
31
+ ref_uri,ref_schema = JSON::Schema::RefAttribute.get_referenced_uri_and_schema(s, current_schema, validator)
33
32
  if ref_schema
34
- # Perform fragment resolution to retrieve the appropriate level for the schema
35
- target_schema = ref_schema.schema
36
- fragments = temp_uri.fragment.split("/")
37
- fragment_path = ''
38
- fragments.each do |fragment|
39
- if fragment && fragment != ''
40
- if target_schema.is_a?(Array)
41
- target_schema = target_schema[fragment.to_i]
42
- else
43
- target_schema = target_schema[fragment]
44
- end
45
- fragment_path = fragment_path + "/#{fragment}"
46
- if target_schema.nil?
47
- raise SchemaError.new("The fragment '#{fragment_path}' does not exist on schema #{ref_schema.uri.to_s}")
48
- end
49
- end
33
+ if s.size == 1 # Check if anything else apart from $ref
34
+ uri,schema = ref_uri,ref_schema
35
+ else
36
+ s = s.dup
37
+ s.delete '$ref'
38
+ s = ref_schema.schema.merge(s)
50
39
  end
51
-
52
- # We have the schema finally, build it and validate!
53
- schema = JSON::Schema.new(target_schema,temp_uri,validator)
54
- schema.validate(data, fragments, options)
55
- else
56
- message = "The extended schema '#{temp_uri.to_s}' cannot be found"
57
- validation_error(message, fragments, current_schema, self, options[:record_errors])
58
40
  end
59
- else
60
- message = "The property '#{build_fragment(fragments)}' was not a valid schema"
61
- validation_error(message, fragments, current_schema, self, options[:record_errors])
62
41
  end
42
+ schema ||= JSON::Schema.new(s,uri,validator)
63
43
  end
44
+
45
+ [uri,schema]
64
46
  end
65
47
  end
66
48
  end
67
- end
49
+ end
@@ -1,12 +1,28 @@
1
1
  module JSON
2
2
  class Schema
3
3
  class RefAttribute < Attribute
4
- def self.validate(current_schema, data, fragments, validator, options = {})
5
- temp_uri = URI.parse(current_schema.schema['$ref'])
4
+ def self.validate(current_schema, data, fragments, validator, options = {})
5
+ uri,schema = get_referenced_uri_and_schema(current_schema.schema, current_schema, validator)
6
+
7
+ if schema
8
+ schema.validate(data, fragments, options)
9
+ elsif uri
10
+ message = "The referenced schema '#{uri.to_s}' cannot be found"
11
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
12
+ else
13
+ message = "The property '#{build_fragment(fragments)}' was not a valid schema"
14
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
15
+ end
16
+ end
17
+
18
+ def self.get_referenced_uri_and_schema(s, current_schema, validator)
19
+ uri,schema = nil,nil
20
+
21
+ temp_uri = URI.parse(s['$ref'])
6
22
  if temp_uri.relative?
7
23
  temp_uri = current_schema.uri.clone
8
24
  # Check for absolute path
9
- path = current_schema.schema['$ref'].split("#")[0]
25
+ path = s['$ref'].split("#")[0]
10
26
  if path.nil? || path == ''
11
27
  temp_uri.path = current_schema.uri.path
12
28
  elsif path[0,1] == "/"
@@ -14,7 +30,7 @@ module JSON
14
30
  else
15
31
  temp_uri = current_schema.uri.merge(path)
16
32
  end
17
- temp_uri.fragment = current_schema.schema['$ref'].split("#")[1]
33
+ temp_uri.fragment = s['$ref'].split("#")[1]
18
34
  end
19
35
  temp_uri.fragment = "" if temp_uri.fragment.nil?
20
36
 
@@ -43,12 +59,11 @@ module JSON
43
59
  end
44
60
 
45
61
  # We have the schema finally, build it and validate!
62
+ uri = temp_uri
46
63
  schema = JSON::Schema.new(target_schema,temp_uri,validator)
47
- schema.validate(data, fragments, options)
48
- else
49
- message = "The referenced schema '#{temp_uri.to_s}' cannot be found"
50
- validation_error(message, fragments, current_schema, self, options[:record_errors])
51
64
  end
65
+
66
+ [uri,schema]
52
67
  end
53
68
  end
54
69
  end
@@ -407,7 +407,7 @@ module JSON
407
407
 
408
408
  def parse(s)
409
409
  if defined?(MultiJson)
410
- MultiJson.respond_to?(:load) ? MultiJson.load(s) : MultiJson.decode(s)
410
+ MultiJson.respond_to?(:adapter) ? MultiJson.load(s) : MultiJson.decode(s)
411
411
  else
412
412
  case @@json_backend.to_s
413
413
  when 'json'
@@ -0,0 +1,34 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-03/schema#",
3
+ "type": "object",
4
+ "extends": "inner.schema.json",
5
+ "properties": {
6
+ "outerA": {
7
+ "description": "blah",
8
+ "required": false,
9
+ "additionalProperties": false,
10
+ "properties": {
11
+ "outerA1": {
12
+ "type":"boolean",
13
+ "required": false
14
+ }
15
+ }
16
+ },
17
+ "outerB": {
18
+ "required": false,
19
+ "type": "array",
20
+ "minItems": 1,
21
+ "maxItems": 50,
22
+ "items": {
23
+ "extends": "inner.schema.json",
24
+ "additionalProperties": false
25
+ }
26
+ },
27
+ "outerC": {
28
+ "description": "blah",
29
+ "type":"boolean",
30
+ "required": false
31
+ }
32
+ },
33
+ "additionalProperties": false
34
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-03/schema#",
3
+ "type": "object",
4
+ "extends": {"$ref":"inner.schema.json#"},
5
+ "properties": {
6
+ "outerA": {
7
+ "description": "blah",
8
+ "required": false,
9
+ "additionalProperties": false,
10
+ "properties": {
11
+ "outerA1": {
12
+ "type":"boolean",
13
+ "required": false
14
+ }
15
+ }
16
+ },
17
+ "outerB": {
18
+ "required": false,
19
+ "type": "array",
20
+ "minItems": 1,
21
+ "maxItems": 50,
22
+ "items": {
23
+ "extends": {"$ref":"inner.schema.json#"},
24
+ "additionalProperties": false
25
+ }
26
+ },
27
+ "outerC": {
28
+ "description": "blah",
29
+ "type":"boolean",
30
+ "required": false
31
+ }
32
+ },
33
+ "additionalProperties": false
34
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-03/schema#",
3
+ "type": "object",
4
+ "extends": "inner.schema.json",
5
+ "additionalProperties": {
6
+ "outerA": {
7
+ "description": "blah",
8
+ "required": false,
9
+ "additionalProperties": false,
10
+ "properties": {
11
+ "outerA1": {
12
+ "type":"boolean",
13
+ "required": false
14
+ }
15
+ }
16
+ },
17
+ "outerB": {
18
+ "required": false,
19
+ "type": "array",
20
+ "minItems": 1,
21
+ "maxItems": 50,
22
+ "items": {
23
+ "extends": "inner.schema.json",
24
+ "additionalProperties": false
25
+ }
26
+ },
27
+ "outerC": {
28
+ "description": "blah",
29
+ "type":"boolean",
30
+ "required": false
31
+ }
32
+ }
33
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-03/schema#",
3
+ "type": "object",
4
+ "extends": {"$ref":"inner.schema.json#"},
5
+ "additionalProperties": {
6
+ "outerA": {
7
+ "description": "blah",
8
+ "required": false,
9
+ "additionalProperties": false,
10
+ "properties": {
11
+ "outerA1": {
12
+ "type":"boolean",
13
+ "required": false
14
+ }
15
+ }
16
+ },
17
+ "outerB": {
18
+ "required": false,
19
+ "type": "array",
20
+ "minItems": 1,
21
+ "maxItems": 50,
22
+ "items": {
23
+ "extends": {"$ref":"inner.schema.json#"},
24
+ "additionalProperties": false
25
+ }
26
+ },
27
+ "outerC": {
28
+ "description": "blah",
29
+ "type":"boolean",
30
+ "required": false
31
+ }
32
+ }
33
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-03/schema#",
3
+ "type": "object",
4
+ "properties": {
5
+ "innerA": {
6
+ "description": "blah",
7
+ "type":"boolean",
8
+ "required": false
9
+ },
10
+ "innerB": {
11
+ "description": "blah",
12
+ "type":"boolean",
13
+ "required": false
14
+ },
15
+ "innerC": {
16
+ "description": "blah",
17
+ "required": false,
18
+ "type": "boolean"
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,50 @@
1
+ require 'test/unit'
2
+ require File.dirname(__FILE__) + '/../lib/json-schema'
3
+
4
+ class ExtendsNestedTest < Test::Unit::TestCase
5
+
6
+ def assert_validity(valid, schema_name, data, msg=nil)
7
+ file = File.expand_path("../schemas/#{schema_name}.schema.json",__FILE__)
8
+ errors = JSON::Validator.fully_validate file, data
9
+ msg.sub! /\.$/, '' if msg
10
+ send (valid ? :assert_equal : :refute_equal), [], errors, \
11
+ "Schema should be #{valid ? :valid : :invalid}#{msg ? ".\n[#{schema_name}] #{msg}" : ''}"
12
+ end
13
+
14
+ def assert_valid(schema_name, data, msg=nil) assert_validity true, schema_name, data, msg end
15
+ def refute_valid(schema_name, data, msg=nil) assert_validity false, schema_name, data, msg end
16
+
17
+ %w[
18
+ extends_and_additionalProperties-1-filename extends_and_additionalProperties-1-ref
19
+ extends_and_additionalProperties-2-filename extends_and_additionalProperties-2-ref
20
+ ].each do |schema_name|
21
+ test_prefix= 'test_' + schema_name.gsub('-','_')
22
+ class_eval <<-EOB
23
+
24
+ def #{test_prefix}_valid_outer
25
+ assert_valid '#{schema_name}', {"outerC"=>true}, "Outer defn is broken, maybe the outer extends overrode it?"
26
+ end
27
+
28
+ def #{test_prefix}_valid_outer_extended
29
+ assert_valid '#{schema_name}', {"innerA"=>true}, "Extends at the root level isn't working."
30
+ end
31
+
32
+ def #{test_prefix}_valid_inner
33
+ assert_valid '#{schema_name}', {"outerB"=>[{"innerA"=>true}]}, "Extends isn't working in the array element defn."
34
+ end
35
+
36
+ def #{test_prefix}_invalid_inner
37
+ refute_valid '#{schema_name}', {"outerB"=>[{"whaaaaat"=>true}]}, "Array element defn allowing anything when it should only allow what's in inner.schema"
38
+ end
39
+ EOB
40
+
41
+ if schema_name['extends_and_additionalProperties-1']
42
+ class_eval <<-EOB
43
+ def #{test_prefix}_invalid_outer
44
+ refute_valid '#{schema_name}', {"whaaaaat"=>true}, "Outer defn allowing anything when it shouldn't."
45
+ end
46
+ EOB
47
+ end
48
+
49
+ end
50
+ end
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.8
4
+ version: 1.0.9
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-06-13 00:00:00.000000000 Z
12
+ date: 2012-08-29 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description:
15
15
  email: hoxworth@gmail.com
@@ -58,6 +58,7 @@ files:
58
58
  - README.textile
59
59
  - LICENSE.md
60
60
  - test/test_extended_schema.rb
61
+ - test/test_extends_and_additionalProperties.rb
61
62
  - test/test_files.rb
62
63
  - test/test_full_validation.rb
63
64
  - test/test_jsonschema_draft1.rb
@@ -66,8 +67,13 @@ files:
66
67
  - test/test_schema_validation.rb
67
68
  - test/data/bad_data_1.json
68
69
  - test/data/good_data_1.json
70
+ - test/schemas/extends_and_additionalProperties-1-filename.schema.json
71
+ - test/schemas/extends_and_additionalProperties-1-ref.schema.json
72
+ - test/schemas/extends_and_additionalProperties-2-filename.schema.json
73
+ - test/schemas/extends_and_additionalProperties-2-ref.schema.json
69
74
  - test/schemas/good_schema_1.json
70
75
  - test/schemas/good_schema_2.json
76
+ - test/schemas/inner.schema.json
71
77
  homepage: http://github.com/hoxworth/json-schema/tree/master
72
78
  licenses: []
73
79
  post_install_message:
@@ -88,12 +94,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
94
  version: '0'
89
95
  requirements: []
90
96
  rubyforge_project:
91
- rubygems_version: 1.8.10
97
+ rubygems_version: 1.8.24
92
98
  signing_key:
93
99
  specification_version: 3
94
100
  summary: Ruby JSON Schema Validator
95
101
  test_files:
96
102
  - test/test_extended_schema.rb
103
+ - test/test_extends_and_additionalProperties.rb
97
104
  - test/test_files.rb
98
105
  - test/test_full_validation.rb
99
106
  - test/test_jsonschema_draft1.rb
@@ -102,5 +109,11 @@ test_files:
102
109
  - test/test_schema_validation.rb
103
110
  - test/data/bad_data_1.json
104
111
  - test/data/good_data_1.json
112
+ - test/schemas/extends_and_additionalProperties-1-filename.schema.json
113
+ - test/schemas/extends_and_additionalProperties-1-ref.schema.json
114
+ - test/schemas/extends_and_additionalProperties-2-filename.schema.json
115
+ - test/schemas/extends_and_additionalProperties-2-ref.schema.json
105
116
  - test/schemas/good_schema_1.json
106
117
  - test/schemas/good_schema_2.json
118
+ - test/schemas/inner.schema.json
119
+ has_rdoc: