json-schema 1.0.3 → 1.0.4

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.3.gem
21
+ $ gem install json-schema-1.0.4.gem
22
22
  </pre>
23
23
 
24
24
 
@@ -5,7 +5,7 @@ module JSON
5
5
  if data.is_a?(Array) && current_schema.schema['items'].is_a?(Array)
6
6
  if current_schema.schema['additionalItems'] == false && current_schema.schema['items'].length != data.length
7
7
  message = "The property '#{build_fragment(fragments)}' contains additional array elements outside of the schema when none are allowed"
8
- validation_error(message, fragments, current_schema, options[:record_errors])
8
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
9
9
  elsif current_schema.schema['additionalItems'].is_a?(Hash)
10
10
  schema = JSON::Schema.new(current_schema.schema['additionalItems'],current_schema.uri,validator)
11
11
  data.each_with_index do |item,i|
@@ -23,7 +23,7 @@ module JSON
23
23
 
24
24
  if current_schema.schema['additionalProperties'] == false && !extra_properties.empty?
25
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, options[:record_errors])
26
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
27
27
  elsif current_schema.schema['additionalProperties'].is_a?(Hash)
28
28
  extra_properties.each do |key|
29
29
  schema = JSON::Schema.new(current_schema.schema['additionalProperties'],current_schema.uri,validator)
@@ -8,13 +8,13 @@ module JSON
8
8
  if dependency_value.is_a?(String)
9
9
  if !data.has_key?(dependency_value)
10
10
  message = "The property '#{build_fragment(fragments)}' has a property '#{property}' that depends on a missing property '#{dependency_value}'"
11
- validation_error(message, fragments, current_schema, options[:record_errors])
11
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
12
12
  end
13
13
  elsif dependency_value.is_a?(Array)
14
14
  dependency_value.each do |value|
15
15
  if !data.has_key?(value)
16
16
  message = "The property '#{build_fragment(fragments)}' has a property '#{property}' that depends on a missing property '#{value}'"
17
- validation_error(message, fragments, current_schema, options[:record_errors])
17
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
18
18
  end
19
19
  end
20
20
  else
@@ -7,7 +7,7 @@ module JSON
7
7
  current_schema.schema['divisibleBy'] == 0.0 ||
8
8
  (BigDecimal.new(data.to_s) % BigDecimal.new(current_schema.schema['divisibleBy'].to_s)).to_f != 0
9
9
  message = "The property '#{build_fragment(fragments)}' was not divisible by #{current_schema.schema['divisibleBy']}"
10
- validation_error(message, fragments, current_schema, options[:record_errors])
10
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
11
11
  end
12
12
  end
13
13
  end
@@ -16,7 +16,7 @@ module JSON
16
16
  end
17
17
  }
18
18
  message.chop!
19
- validation_error(message, fragments, current_schema, options[:record_errors])
19
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
20
20
  end
21
21
  end
22
22
  end
@@ -8,26 +8,26 @@ module JSON
8
8
  when 'date-time'
9
9
  if data.is_a?(String)
10
10
  error_message = "The property '#{build_fragment(fragments)}' must be a date/time in the ISO-8601 format of YYYY-MM-DDThh:mm:ssZ"
11
- validation_error(error_message, fragments, current_schema, options[:record_errors]) and return if !data.is_a?(String)
11
+ validation_error(error_message, fragments, current_schema, self, options[:record_errors]) and return if !data.is_a?(String)
12
12
  r = Regexp.new('^\d\d\d\d-\d\d-\d\dT(\d\d):(\d\d):(\d\d)Z$')
13
13
  if (m = r.match(data))
14
14
  parts = data.split("T")
15
15
  begin
16
16
  Date.parse(parts[0])
17
17
  rescue Exception
18
- validation_error(error_message, fragments, current_schema, options[:record_errors])
18
+ validation_error(error_message, fragments, current_schema, self, options[:record_errors])
19
19
  return
20
20
  end
21
21
  begin
22
- validation_error(error_message, fragments, current_schema, options[:record_errors]) and return if m[1].to_i > 23
23
- validation_error(error_message, fragments, current_schema, options[:record_errors]) and return if m[2].to_i > 59
24
- validation_error(error_message, fragments, current_schema, options[:record_errors]) and return if m[3].to_i > 59
22
+ validation_error(error_message, fragments, current_schema, self, options[:record_errors]) and return if m[1].to_i > 23
23
+ validation_error(error_message, fragments, current_schema, self, options[:record_errors]) and return if m[2].to_i > 59
24
+ validation_error(error_message, fragments, current_schema, self, options[:record_errors]) and return if m[3].to_i > 59
25
25
  rescue Exception
26
- validation_error(error_message, fragments, current_schema, options[:record_errors])
26
+ validation_error(error_message, fragments, current_schema, self, options[:record_errors])
27
27
  return
28
28
  end
29
29
  else
30
- validation_error(error_message, fragments, current_schema, options[:record_errors])
30
+ validation_error(error_message, fragments, current_schema, self, options[:record_errors])
31
31
  return
32
32
  end
33
33
  end
@@ -36,17 +36,17 @@ module JSON
36
36
  when 'date'
37
37
  if data.is_a?(String)
38
38
  error_message = "The property '#{build_fragment(fragments)}' must be a date in the format of YYYY-MM-DD"
39
- validation_error(error_message, fragments, current_schema, options[:record_errors]) and return if !data.is_a?(String)
39
+ validation_error(error_message, fragments, current_schema, self, options[:record_errors]) and return if !data.is_a?(String)
40
40
  r = Regexp.new('^\d\d\d\d-\d\d-\d\d$')
41
41
  if (m = r.match(data))
42
42
  begin
43
43
  Date.parse(data)
44
44
  rescue Exception
45
- validation_error(error_message, fragments, current_schema, options[:record_errors])
45
+ validation_error(error_message, fragments, current_schema, self, options[:record_errors])
46
46
  return
47
47
  end
48
48
  else
49
- validation_error(error_message, fragments, current_schema, options[:record_errors])
49
+ validation_error(error_message, fragments, current_schema, self, options[:record_errors])
50
50
  return
51
51
  end
52
52
  end
@@ -55,14 +55,14 @@ module JSON
55
55
  when 'time'
56
56
  if data.is_a?(String)
57
57
  error_message = "The property '#{build_fragment(fragments)}' must be a time in the format of hh:mm:ss"
58
- validation_error(error_message, fragments, current_schema, options[:record_errors]) and return if !data.is_a?(String)
58
+ validation_error(error_message, fragments, current_schema, self, options[:record_errors]) and return if !data.is_a?(String)
59
59
  r = Regexp.new('^(\d\d):(\d\d):(\d\d)$')
60
60
  if (m = r.match(data))
61
- validation_error(error_message, fragments, current_schema, options[:record_errors]) and return if m[1].to_i > 23
62
- validation_error(error_message, fragments, current_schema, options[:record_errors]) and return if m[2].to_i > 59
63
- validation_error(error_message, fragments, current_schema, options[:record_errors]) and return if m[3].to_i > 59
61
+ validation_error(error_message, fragments, current_schema, self, options[:record_errors]) and return if m[1].to_i > 23
62
+ validation_error(error_message, fragments, current_schema, self, options[:record_errors]) and return if m[2].to_i > 59
63
+ validation_error(error_message, fragments, current_schema, self, options[:record_errors]) and return if m[3].to_i > 59
64
64
  else
65
- validation_error(error_message, fragments, current_schema, options[:record_errors])
65
+ validation_error(error_message, fragments, current_schema, self, options[:record_errors])
66
66
  return
67
67
  end
68
68
  end
@@ -71,14 +71,14 @@ module JSON
71
71
  when 'ip-address', 'ipv4'
72
72
  if data.is_a?(String)
73
73
  error_message = "The property '#{build_fragment(fragments)}' must be a valid IPv4 address"
74
- validation_error(error_message, fragments, current_schema, options[:record_errors]) and return if !data.is_a?(String)
74
+ validation_error(error_message, fragments, current_schema, self, options[:record_errors]) and return if !data.is_a?(String)
75
75
  r = Regexp.new('^(\d+){1,3}\.(\d+){1,3}\.(\d+){1,3}\.(\d+){1,3}$')
76
76
  if (m = r.match(data))
77
77
  1.upto(4) do |x|
78
- validation_error(error_message, fragments, current_schema, options[:record_errors]) and return if m[x].to_i > 255
78
+ validation_error(error_message, fragments, current_schema, self, options[:record_errors]) and return if m[x].to_i > 255
79
79
  end
80
80
  else
81
- validation_error(error_message, fragments, current_schema, options[:record_errors])
81
+ validation_error(error_message, fragments, current_schema, self, options[:record_errors])
82
82
  return
83
83
  end
84
84
  end
@@ -87,22 +87,22 @@ module JSON
87
87
  when 'ipv6'
88
88
  if data.is_a?(String)
89
89
  error_message = "The property '#{build_fragment(fragments)}' must be a valid IPv6 address"
90
- validation_error(error_message, fragments, current_schema, options[:record_errors]) and return if !data.is_a?(String)
90
+ validation_error(error_message, fragments, current_schema, self, options[:record_errors]) and return if !data.is_a?(String)
91
91
  r = Regexp.new('^[a-f0-9:]+$')
92
92
  if (m = r.match(data))
93
93
  # All characters are valid, now validate structure
94
94
  parts = data.split(":")
95
- validation_error(error_message, fragments, current_schema, options[:record_errors]) and return if parts.length > 8
95
+ validation_error(error_message, fragments, current_schema, self, options[:record_errors]) and return if parts.length > 8
96
96
  condensed_zeros = false
97
97
  parts.each do |part|
98
98
  if part.length == 0
99
- validation_error(error_message, fragments, current_schema, options[:record_errors]) and return if condensed_zeros
99
+ validation_error(error_message, fragments, current_schema, self, options[:record_errors]) and return if condensed_zeros
100
100
  condensed_zeros = true
101
101
  end
102
- validation_error(error_message, fragments, current_schema, options[:record_errors]) and return if part.length > 4
102
+ validation_error(error_message, fragments, current_schema, self, options[:record_errors]) and return if part.length > 4
103
103
  end
104
104
  else
105
- validation_error(error_message, fragments, current_schema, options[:record_errors])
105
+ validation_error(error_message, fragments, current_schema, self, options[:record_errors])
106
106
  return
107
107
  end
108
108
  end
@@ -6,7 +6,7 @@ module JSON
6
6
  s = data.to_s.split(".")[1]
7
7
  if s && s.length > current_schema.schema['maxDecimal']
8
8
  message = "The property '#{build_fragment(fragments)}' had more decimal places than the allowed #{current_schema.schema['maxDecimal']}"
9
- validation_error(message, fragments, current_schema, options[:record_errors])
9
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
10
10
  end
11
11
  end
12
12
  end
@@ -6,7 +6,7 @@ module JSON
6
6
  if (current_schema.schema['exclusiveMaximum'] ? data >= current_schema.schema['maximum'] : data > current_schema.schema['maximum'])
7
7
  message = "The property '#{build_fragment(fragments)}' did not have a maximum value of #{current_schema.schema['maximum']}, "
8
8
  message += current_schema.schema['exclusiveMaximum'] ? 'exclusively' : 'inclusively'
9
- validation_error(message, fragments, current_schema, options[:record_errors])
9
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
10
10
  end
11
11
  end
12
12
  end
@@ -6,7 +6,7 @@ module JSON
6
6
  if (current_schema.schema['maximumCanEqual'] == false ? data >= current_schema.schema['maximum'] : data > current_schema.schema['maximum'])
7
7
  message = "The property '#{build_fragment(fragments)}' did not have a maximum value of #{current_schema.schema['maximum']}, "
8
8
  message += current_schema.schema['exclusiveMaximum'] ? 'exclusively' : 'inclusively'
9
- validation_error(message, fragments, current_schema, options[:record_errors])
9
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
10
10
  end
11
11
  end
12
12
  end
@@ -4,7 +4,7 @@ module JSON
4
4
  def self.validate(current_schema, data, fragments, validator, options = {})
5
5
  if data.is_a?(Array) && (data.compact.size > current_schema.schema['maxItems'])
6
6
  message = "The property '#{build_fragment(fragments)}' did not contain a minimum number of items #{current_schema.schema['minItems']}"
7
- validation_error(message, fragments, current_schema, options[:record_errors])
7
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
8
8
  end
9
9
  end
10
10
  end
@@ -5,7 +5,7 @@ module JSON
5
5
  if data.is_a?(String)
6
6
  if data.length > current_schema.schema['maxLength']
7
7
  message = "The property '#{build_fragment(fragments)}' was not of a maximum string length of #{current_schema.schema['maxLength']}"
8
- validation_error(message, fragments, current_schema, options[:record_errors])
8
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
9
9
  end
10
10
  end
11
11
  end
@@ -6,7 +6,7 @@ module JSON
6
6
  if (current_schema.schema['exclusiveMinimum'] ? data <= current_schema.schema['minimum'] : data < current_schema.schema['minimum'])
7
7
  message = "The property '#{build_fragment(fragments)}' did not have a minimum value of #{current_schema.schema['minimum']}, "
8
8
  message += current_schema.schema['exclusiveMinimum'] ? 'exclusively' : 'inclusively'
9
- validation_error(message, fragments, current_schema, options[:record_errors])
9
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
10
10
  end
11
11
  end
12
12
  end
@@ -6,7 +6,7 @@ module JSON
6
6
  if (current_schema.schema['minimumCanEqual'] == false ? data <= current_schema.schema['minimum'] : data < current_schema.schema['minimum'])
7
7
  message = "The property '#{build_fragment(fragments)}' did not have a minimum value of #{current_schema.schema['minimum']}, "
8
8
  message += current_schema.schema['exclusiveMinimum'] ? 'exclusively' : 'inclusively'
9
- validation_error(message, fragments, current_schema, options[:record_errors])
9
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
10
10
  end
11
11
  end
12
12
  end
@@ -4,7 +4,7 @@ module JSON
4
4
  def self.validate(current_schema, data, fragments, validator, options = {})
5
5
  if data.is_a?(Array) && (data.compact.size < current_schema.schema['minItems'])
6
6
  message = "The property '#{build_fragment(fragments)}' did not contain a minimum number of items #{current_schema.schema['minItems']}"
7
- validation_error(message, fragments, current_schema, options[:record_errors])
7
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
8
8
  end
9
9
  end
10
10
  end
@@ -5,7 +5,7 @@ module JSON
5
5
  if data.is_a?(String)
6
6
  if data.length < current_schema.schema['minLength']
7
7
  message = "The property '#{build_fragment(fragments)}' was not of a minimum string length of #{current_schema.schema['minLength']}"
8
- validation_error(message, fragments, current_schema, options[:record_errors])
8
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
9
9
  end
10
10
  end
11
11
  end
@@ -6,7 +6,7 @@ module JSON
6
6
  r = Regexp.new(current_schema.schema['pattern'])
7
7
  if (r.match(data)).nil?
8
8
  message = "The property '#{build_fragment(fragments)}' did not match the regex '#{current_schema.schema['pattern']}'"
9
- validation_error(message, fragments, current_schema, options[:record_errors])
9
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
10
10
  end
11
11
  end
12
12
  end
@@ -6,7 +6,7 @@ module JSON
6
6
  current_schema.schema['properties'].each do |property,property_schema|
7
7
  if (property_schema['required'] && !data.has_key?(property))
8
8
  message = "The property '#{build_fragment(fragments)}' did not contain a required property of '#{property}'"
9
- validation_error(message, fragments, current_schema, options[:record_errors])
9
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
10
10
  end
11
11
 
12
12
  if data.has_key?(property)
@@ -6,7 +6,7 @@ module JSON
6
6
  current_schema.schema['properties'].each do |property,property_schema|
7
7
  if ((property_schema['optional'].nil? || property_schema['optional'] == false) && !data.has_key?(property))
8
8
  message = "The property '#{build_fragment(fragments)}' did not contain a required property of '#{property}'"
9
- validation_error(message, fragments, current_schema, options[:record_errors])
9
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
10
10
  end
11
11
 
12
12
  if data.has_key?(property)
@@ -47,7 +47,7 @@ module JSON
47
47
  schema.validate(data, fragments, options)
48
48
  else
49
49
  message = "The referenced schema '#{temp_uri.to_s}' cannot be found"
50
- validation_error(message, fragments, current_schema, options[:record_errors])
50
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
51
51
  end
52
52
  end
53
53
  end
@@ -15,7 +15,10 @@ module JSON
15
15
  union = false
16
16
  end
17
17
  valid = false
18
-
18
+
19
+ # Create an array to hold errors that are generated during union validation
20
+ union_errors = []
21
+
19
22
  types.each do |type|
20
23
  if type.is_a?(String)
21
24
  case type
@@ -41,12 +44,24 @@ module JSON
41
44
  elsif type.is_a?(Hash) && union
42
45
  # Validate as a schema
43
46
  schema = JSON::Schema.new(type,current_schema.uri,validator)
47
+
48
+ # We're going to add a little cruft here to try and maintain any validation errors that occur in this union type
49
+ # We'll handle this by keeping an error count before and after validation, extracting those errors and pushing them onto a union error
50
+ pre_validation_error_count = validation_errors.count
51
+
44
52
  begin
45
53
  schema.validate(data,fragments,options)
46
54
  valid = true
47
55
  rescue ValidationError
48
56
  # We don't care that these schemas don't validate - we only care that one validated
49
57
  end
58
+
59
+ diff = validation_errors.count - pre_validation_error_count
60
+ valid = false if diff > 0
61
+ while diff > 0
62
+ diff = diff - 1
63
+ union_errors.push(validation_errors.pop)
64
+ end
50
65
  end
51
66
 
52
67
  break if valid
@@ -57,13 +72,21 @@ module JSON
57
72
  message = "The property '#{build_fragment(fragments)}' matched one or more of the following types:"
58
73
  types.each {|type| message += type.is_a?(String) ? " #{type}," : " (schema)," }
59
74
  message.chop!
60
- validation_error(message, fragments, current_schema, options[:record_errors])
75
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
61
76
  end
62
77
  elsif !valid
63
- message = "The property '#{build_fragment(fragments)}' of type #{data.class} did not match one or more of the following types:"
64
- types.each {|type| message += type.is_a?(String) ? " #{type}," : " (schema)," }
65
- message.chop!
66
- validation_error(message, fragments, current_schema, options[:record_errors])
78
+ if union
79
+ message = "The property '#{build_fragment(fragments)}' of type #{data.class} did not match one or more of the following types:"
80
+ types.each {|type| message += type.is_a?(String) ? " #{type}," : " (schema)," }
81
+ message.chop!
82
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
83
+ validation_errors.last.sub_errors = union_errors
84
+ else
85
+ message = "The property '#{build_fragment(fragments)}' of type #{data.class} did not match the following type:"
86
+ types.each {|type| message += type.is_a?(String) ? " #{type}," : " (schema)," }
87
+ message.chop!
88
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
89
+ end
67
90
  end
68
91
  end
69
92
  end
@@ -7,7 +7,7 @@ module JSON
7
7
  dupes = d.uniq!
8
8
  if dupes
9
9
  message = "The property '#{build_fragment(fragments)}' contained duplicated array values"
10
- validation_error(message, fragments, current_schema, options[:record_errors])
10
+ validation_error(message, fragments, current_schema, self, options[:record_errors])
11
11
  end
12
12
  end
13
13
  end
@@ -44,7 +44,9 @@ module JSON
44
44
  parts.join('/') + '/'
45
45
  end
46
46
 
47
-
47
+ def to_s
48
+ @schema.to_json
49
+ end
48
50
  end
49
51
  end
50
52
 
@@ -9,14 +9,34 @@ module JSON
9
9
 
10
10
  class Schema
11
11
  class ValidationError < StandardError
12
- attr_reader :fragments, :schema
12
+ attr_accessor :fragments, :schema, :failed_attribute, :sub_errors
13
13
 
14
- def initialize(message, fragments, schema)
15
- @fragments = fragments
14
+ def initialize(message, fragments, failed_attribute, schema)
15
+ @fragments = fragments.clone
16
16
  @schema = schema
17
+ @sub_errors = []
18
+ @failed_attribute = failed_attribute
17
19
  message = "#{message} in schema #{schema.uri}"
18
20
  super(message)
19
21
  end
22
+
23
+ def to_string
24
+ if @sub_errors.empty?
25
+ message
26
+ else
27
+ full_message = message + "\n The schema specific errors were:\n"
28
+ @sub_errors.each{|e| full_message = full_message + " - " + e.to_string + "\n"}
29
+ full_message
30
+ end
31
+ end
32
+
33
+ def to_hash
34
+ base = {:schema => @schema.uri, :fragment => ::JSON::Schema::Attribute.build_fragment(fragments), :message => message, :failed_attribute => @failed_attribute.to_s.split(":").last.split("Attribute").first}
35
+ if !@sub_errors.empty?
36
+ base[:errors] = @sub_errors.map{|e| e.to_hash}
37
+ end
38
+ base
39
+ end
20
40
  end
21
41
 
22
42
  class SchemaError < StandardError
@@ -33,14 +53,18 @@ module JSON
33
53
  "#/#{fragments.join('/')}"
34
54
  end
35
55
 
36
- def self.validation_error(message, fragments, current_schema, record_errors)
37
- error = ValidationError.new(message, fragments, current_schema)
56
+ def self.validation_error(message, fragments, current_schema, failed_attribute, record_errors)
57
+ error = ValidationError.new(message, fragments, failed_attribute, current_schema)
38
58
  if record_errors
39
- ::JSON::Validator.validation_error(error.message)
59
+ ::JSON::Validator.validation_error(error)
40
60
  else
41
61
  raise error
42
62
  end
43
63
  end
64
+
65
+ def self.validation_errors
66
+ ::JSON::Validator.validation_errors
67
+ end
44
68
  end
45
69
 
46
70
  class Validator
@@ -84,7 +108,8 @@ module JSON
84
108
  :list => false,
85
109
  :version => nil,
86
110
  :validate_schema => false,
87
- :record_errors => false
111
+ :record_errors => false,
112
+ :errors_as_objects => false
88
113
  }
89
114
  @@validators = {}
90
115
  @@default_validator = nil
@@ -148,7 +173,11 @@ module JSON
148
173
  Validator.clear_errors
149
174
  @base_schema.validate(@data,[],@validation_options)
150
175
  Validator.clear_cache
151
- @@errors
176
+ if @options[:errors_as_objects]
177
+ @@errors.map{|e| e.to_hash}
178
+ else
179
+ @@errors.map{|e| e.to_string}
180
+ end
152
181
  rescue JSON::Schema::ValidationError
153
182
  Validator.clear_cache
154
183
  raise $!
@@ -294,6 +323,10 @@ module JSON
294
323
  def validation_error(error)
295
324
  @@errors.push(error)
296
325
  end
326
+
327
+ def validation_errors
328
+ @@errors
329
+ end
297
330
 
298
331
  def schemas
299
332
  @@schemas
@@ -5,7 +5,7 @@ class BitwiseAndAttribute < JSON::Schema::Attribute
5
5
  def self.validate(current_schema, data, fragments, validator, options = {})
6
6
  if data.is_a?(Integer) && data & current_schema.schema['bitwise-and'].to_i == 0
7
7
  message = "The property '#{build_fragment(fragments)}' did not evaluate to true when bitwise-AND'd with #{current_schema.schema['bitwise-or']}"
8
- raise JSON::Schema::ValidationError.new(message, fragments, current_schema)
8
+ raise JSON::Schema::ValidationError.new(message, fragments, self, current_schema)
9
9
  end
10
10
  end
11
11
  end
data/test/test_files.rb CHANGED
@@ -8,36 +8,28 @@ class JSONSchemaTest < Test::Unit::TestCase
8
8
  #
9
9
 
10
10
  def test_schema_from_file
11
- if JSON::Validator.json_backend != nil
12
- data = {"a" => 5}
13
- assert(JSON::Validator.validate(File.join(File.dirname(__FILE__),"schemas/good_schema_1.json"),data))
14
- data = {"a" => "bad"}
15
- assert(!JSON::Validator.validate(File.join(File.dirname(__FILE__),"schemas/good_schema_1.json"),data))
16
- end
11
+ data = {"a" => 5}
12
+ assert(JSON::Validator.validate(File.join(File.dirname(__FILE__),"schemas/good_schema_1.json"),data))
13
+ data = {"a" => "bad"}
14
+ assert(!JSON::Validator.validate(File.join(File.dirname(__FILE__),"schemas/good_schema_1.json"),data))
17
15
  end
18
16
 
19
17
  def test_data_from_file
20
- if JSON::Validator.json_backend != nil
21
- schema = {"type" => "object", "properties" => {"a" => {"type" => "integer"}}}
22
- assert(JSON::Validator.validate(schema,File.join(File.dirname(__FILE__),"data/good_data_1.json")))
23
- assert(!JSON::Validator.validate(schema,File.join(File.dirname(__FILE__),"data/bad_data_1.json")))
24
- end
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")))
25
21
  end
26
22
 
27
23
  def test_both_from_file
28
- if JSON::Validator.json_backend != nil
29
- assert(JSON::Validator.validate(File.join(File.dirname(__FILE__),"schemas/good_schema_1.json"),File.join(File.dirname(__FILE__),"data/good_data_1.json")))
30
- assert(!JSON::Validator.validate(File.join(File.dirname(__FILE__),"schemas/good_schema_1.json"),File.join(File.dirname(__FILE__),"data/bad_data_1.json")))
31
- end
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
26
  end
33
27
 
34
28
  def test_file_ref
35
- if JSON::Validator.json_backend != nil
36
- data = {"b" => {"a" => 5}}
37
- assert(JSON::Validator.validate(File.join(File.dirname(__FILE__),"schemas/good_schema_2.json"),data))
38
-
39
- data = {"b" => {"a" => "boo"}}
40
- assert(!JSON::Validator.validate(File.join(File.dirname(__FILE__),"schemas/good_schema_1.json"),data))
41
- end
29
+ data = {"b" => {"a" => 5}}
30
+ assert(JSON::Validator.validate(File.join(File.dirname(__FILE__),"schemas/good_schema_2.json"),data))
31
+
32
+ data = {"b" => {"a" => "boo"}}
33
+ assert(!JSON::Validator.validate(File.join(File.dirname(__FILE__),"schemas/good_schema_1.json"),data))
42
34
  end
43
35
  end
@@ -35,4 +35,114 @@ class JSONFullValidation < Test::Unit::TestCase
35
35
  errors = JSON::Validator.fully_validate(schema,data)
36
36
  assert(errors.length == 2)
37
37
  end
38
+
39
+ def test_full_validation_with_union_types
40
+ data = {"b" => 5}
41
+ schema = {
42
+ "$schema" => "http://json-schema.org/draft-03/schema#",
43
+ "type" => "object",
44
+ "properties" => {
45
+ "b" => {
46
+ "type" => ["null","integer"]
47
+ }
48
+ }
49
+ }
50
+
51
+ errors = JSON::Validator.fully_validate(schema,data)
52
+ assert(errors.empty?)
53
+
54
+ schema = {
55
+ "$schema" => "http://json-schema.org/draft-03/schema#",
56
+ "type" => "object",
57
+ "properties" => {
58
+ "b" => {
59
+ "type" => ["integer","null"]
60
+ }
61
+ }
62
+ }
63
+
64
+ errors = JSON::Validator.fully_validate(schema,data)
65
+ assert(errors.empty?)
66
+
67
+ data = {"b" => "a string"}
68
+
69
+ errors = JSON::Validator.fully_validate(schema,data)
70
+ assert(errors.length == 1)
71
+
72
+ schema = {
73
+ "$schema" => "http://json-schema.org/draft-03/schema#",
74
+ "type" => "object",
75
+ "properties" => {
76
+ "b" => {
77
+ "type" => [
78
+ {
79
+ "type" => "object",
80
+ "properties" => {
81
+ "c" => {"type" => "string"}
82
+ }
83
+ },
84
+ {
85
+ "type" => "object",
86
+ "properties" => {
87
+ "d" => {"type" => "integer"}
88
+ }
89
+ }
90
+ ]
91
+ }
92
+ }
93
+ }
94
+
95
+ data = {"b" => {"c" => "taco"}}
96
+
97
+ errors = JSON::Validator.fully_validate(schema,data)
98
+ assert(errors.empty?)
99
+
100
+ data = {"b" => {"d" => 6}}
101
+
102
+ errors = JSON::Validator.fully_validate(schema,data)
103
+ assert(errors.empty?)
104
+
105
+ data = {"b" => {"c" => 6, "d" => "OH GOD"}}
106
+
107
+ errors = JSON::Validator.fully_validate(schema,data)
108
+ assert(errors.length == 1)
109
+ end
110
+
111
+
112
+ def test_full_validation_with_object_errors
113
+ data = {"b" => {"a" => 5}}
114
+ schema = {
115
+ "$schema" => "http://json-schema.org/draft-03/schema#",
116
+ "type" => "object",
117
+ "properties" => {
118
+ "b" => {
119
+ "required" => true
120
+ }
121
+ }
122
+ }
123
+
124
+ errors = JSON::Validator.fully_validate(schema,data,:errors_as_objects => true)
125
+ assert(errors.empty?)
126
+
127
+ data = {"c" => 5}
128
+ schema = {
129
+ "$schema" => "http://json-schema.org/draft-03/schema#",
130
+ "type" => "object",
131
+ "properties" => {
132
+ "b" => {
133
+ "required" => true
134
+ },
135
+ "c" => {
136
+ "type" => "string"
137
+ }
138
+ }
139
+ }
140
+
141
+ errors = JSON::Validator.fully_validate(schema,data,:errors_as_objects => true)
142
+ assert(errors.length == 2)
143
+ assert(errors[0][:failed_attribute] == "Properties")
144
+ assert(errors[0][:fragment] == "#/")
145
+ assert(errors[1][:failed_attribute] == "Type")
146
+ assert(errors[1][:fragment] == "#/c")
147
+ end
38
148
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 1
7
7
  - 0
8
- - 3
9
- version: 1.0.3
8
+ - 4
9
+ version: 1.0.4
10
10
  platform: ruby
11
11
  authors:
12
12
  - Kenny Hoxworth