json-schema 1.0.3 → 1.0.4

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.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