json-schema 0.9.12 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -18,15 +18,15 @@ From the git repo:
18
18
 
19
19
  <pre>
20
20
  $ gem build json-schema.gemspec
21
- $ gem install json-schema-0.9.12.gem
21
+ $ gem install json-schema-1.0.0.gem
22
22
  </pre>
23
23
 
24
24
 
25
25
  h2. Usage
26
26
 
27
- Two base validation methods exist: <code>validate</code> and <code>validate!</code>. The first returns a boolean on whether a validation attempt passes and the latter will throw a <code>JSON::Schema::ValidationError</code> with an appropriate message/trace on where the validation failed.
27
+ Three base validation methods exist: <code>validate</code>, <code>validate!</code>, and <code>fully_validate</code>. The first returns a boolean on whether a validation attempt passes and the second will throw a <code>JSON::Schema::ValidationError</code> with an appropriate message/trace on where the validation failed. The third validation method does not immediately fail upon a validation error and instead builds an array of validation errors return when validation is complete.
28
28
 
29
- Both methods take two arguments, which can be either a JSON string, a file containing JSON, or a Ruby object representing JSON data. The first argument to these methods is always the schema, the second is always the data to validate. An optional third options argument is also accepted; available options are used in the examples below.
29
+ All methods take two arguments, which can be either a JSON string, a file containing JSON, or a Ruby object representing JSON data. The first argument to these methods is always the schema, the second is always the data to validate. An optional third options argument is also accepted; available options are used in the examples below.
30
30
 
31
31
  By default, the validator uses the "JSON Schema Draft 3":http://tools.ietf.org/html/draft-zyp-json-schema-03 specification for validation; however, the user is free to specify additional specifications or extend existing ones. Legacy support for Draft 1 and Draft 2 is included by either passing an optional <code>:version</code> parameter to the <code>validate</code> method (set either as <code>:draft1</code> or <code>draft2</code>), or by declaring the <code>$schema</code> attribute in the schema and referencing the appropriate specification URI. Note that the <code>$schema</code> attribute takes precedence over the <code>:version</code> option during parsing and validation.
32
32
 
@@ -5,13 +5,13 @@ 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
- raise ValidationError.new(message, fragments, current_schema)
8
+ validation_error(message, fragments, current_schema, 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|
12
12
  if i >= current_schema.schema['items'].length
13
13
  fragments << i.to_s
14
- schema.validate(item, fragments)
14
+ schema.validate(item, fragments, options)
15
15
  fragments.pop
16
16
  end
17
17
  end
@@ -23,12 +23,12 @@ 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 outside of the schema when none are allowed"
26
- raise ValidationError.new(message, fragments, current_schema)
26
+ validation_error(message, fragments, current_schema, 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)
30
30
  fragments << key
31
- schema.validate(data[key],fragments)
31
+ schema.validate(data[key],fragments,options)
32
32
  fragments.pop
33
33
  end
34
34
  end
@@ -8,18 +8,18 @@ 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
- raise ValidationError.new(message, fragments, current_schema)
11
+ validation_error(message, fragments, current_schema, 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
- raise ValidationError.new(message, fragments, current_schema)
17
+ validation_error(message, fragments, current_schema, options[:record_errors])
18
18
  end
19
19
  end
20
20
  else
21
21
  schema = JSON::Schema.new(dependency_value,current_schema.uri,validator)
22
- schema.validate(data, fragments)
22
+ schema.validate(data, fragments, options)
23
23
  end
24
24
  end
25
25
  end
@@ -3,7 +3,7 @@ module JSON
3
3
  class DisallowAttribute < Attribute
4
4
  def self.validate(current_schema, data, fragments, validator, options = {})
5
5
  if validator.attributes['type']
6
- validator.attributes['type'].validate(current_schema, data, fragments, validator, {:disallow => true})
6
+ validator.attributes['type'].validate(current_schema, data, fragments, validator, {:disallow => true}.merge(options))
7
7
  end
8
8
  end
9
9
  end
@@ -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
- raise ValidationError.new(message, fragments, current_schema)
10
+ validation_error(message, fragments, current_schema, 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
- raise ValidationError.new(message, fragments, current_schema)
19
+ validation_error(message, fragments, current_schema, options[:record_errors])
20
20
  end
21
21
  end
22
22
  end
@@ -6,7 +6,7 @@ module JSON
6
6
  schemas = [schemas] if !schemas.is_a?(Array)
7
7
  schemas.each do |s|
8
8
  schema = JSON::Schema.new(s,current_schema.uri,validator)
9
- schema.validate(data, fragments)
9
+ schema.validate(data, fragments, options)
10
10
  end
11
11
  end
12
12
  end
@@ -8,24 +8,27 @@ 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
- raise ValidationError.new(error_message, fragments, current_schema) if !data.is_a?(String)
11
+ validation_error(error_message, fragments, current_schema, 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
- raise ValidationError.new(error_message, fragments, current_schema)
18
+ validation_error(error_message, fragments, current_schema, options[:record_errors])
19
+ return
19
20
  end
20
21
  begin
21
- raise ValidationError.new(error_message, fragments, current_schema) if m[1].to_i > 23
22
- raise ValidationError.new(error_message, fragments, current_schema) if m[2].to_i > 59
23
- raise ValidationError.new(error_message, fragments, current_schema) if m[3].to_i > 59
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
24
25
  rescue Exception
25
- raise ValidationError.new(error_message, fragments, current_schema)
26
+ validation_error(error_message, fragments, current_schema, options[:record_errors])
27
+ return
26
28
  end
27
29
  else
28
- raise ValidationError.new(error_message, fragments, current_schema)
30
+ validation_error(error_message, fragments, current_schema, options[:record_errors])
31
+ return
29
32
  end
30
33
  end
31
34
 
@@ -33,16 +36,18 @@ module JSON
33
36
  when 'date'
34
37
  if data.is_a?(String)
35
38
  error_message = "The property '#{build_fragment(fragments)}' must be a date in the format of YYYY-MM-DD"
36
- raise ValidationError.new(error_message, fragments, current_schema) if !data.is_a?(String)
39
+ validation_error(error_message, fragments, current_schema, options[:record_errors]) and return if !data.is_a?(String)
37
40
  r = Regexp.new('^\d\d\d\d-\d\d-\d\d$')
38
41
  if (m = r.match(data))
39
42
  begin
40
43
  Date.parse(data)
41
44
  rescue Exception
42
- raise ValidationError.new(error_message, fragments, current_schema)
45
+ validation_error(error_message, fragments, current_schema, options[:record_errors])
46
+ return
43
47
  end
44
48
  else
45
- raise ValidationError.new(error_message, fragments, current_schema)
49
+ validation_error(error_message, fragments, current_schema, options[:record_errors])
50
+ return
46
51
  end
47
52
  end
48
53
 
@@ -50,14 +55,15 @@ module JSON
50
55
  when 'time'
51
56
  if data.is_a?(String)
52
57
  error_message = "The property '#{build_fragment(fragments)}' must be a time in the format of hh:mm:ss"
53
- raise ValidationError.new(error_message, fragments, current_schema) if !data.is_a?(String)
58
+ validation_error(error_message, fragments, current_schema, options[:record_errors]) and return if !data.is_a?(String)
54
59
  r = Regexp.new('^(\d\d):(\d\d):(\d\d)$')
55
60
  if (m = r.match(data))
56
- raise ValidationError.new(error_message, fragments, current_schema) if m[1].to_i > 23
57
- raise ValidationError.new(error_message, fragments, current_schema) if m[2].to_i > 59
58
- raise ValidationError.new(error_message, fragments, current_schema) if m[3].to_i > 59
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
59
64
  else
60
- raise ValidationError.new(error_message, fragments, current_schema)
65
+ validation_error(error_message, fragments, current_schema, options[:record_errors])
66
+ return
61
67
  end
62
68
  end
63
69
 
@@ -65,14 +71,15 @@ module JSON
65
71
  when 'ip-address', 'ipv4'
66
72
  if data.is_a?(String)
67
73
  error_message = "The property '#{build_fragment(fragments)}' must be a valid IPv4 address"
68
- raise ValidationError.new(error_message, fragments, current_schema) if !data.is_a?(String)
74
+ validation_error(error_message, fragments, current_schema, options[:record_errors]) and return if !data.is_a?(String)
69
75
  r = Regexp.new('^(\d+){1,3}\.(\d+){1,3}\.(\d+){1,3}\.(\d+){1,3}$')
70
76
  if (m = r.match(data))
71
77
  1.upto(4) do |x|
72
- raise ValidationError.new(error_message, fragments, current_schema) if m[x].to_i > 255
78
+ validation_error(error_message, fragments, current_schema, options[:record_errors]) and return if m[x].to_i > 255
73
79
  end
74
80
  else
75
- raise ValidationError.new(error_message, fragments, current_schema)
81
+ validation_error(error_message, fragments, current_schema, options[:record_errors])
82
+ return
76
83
  end
77
84
  end
78
85
 
@@ -80,22 +87,23 @@ module JSON
80
87
  when 'ipv6'
81
88
  if data.is_a?(String)
82
89
  error_message = "The property '#{build_fragment(fragments)}' must be a valid IPv6 address"
83
- raise ValidationError.new(error_message, fragments, current_schema) if !data.is_a?(String)
90
+ validation_error(error_message, fragments, current_schema, options[:record_errors]) and return if !data.is_a?(String)
84
91
  r = Regexp.new('^[a-f0-9:]+$')
85
92
  if (m = r.match(data))
86
93
  # All characters are valid, now validate structure
87
94
  parts = data.split(":")
88
- raise ValidationError.new(error_message, fragments, current_schema) if parts.length > 8
95
+ validation_error(error_message, fragments, current_schema, options[:record_errors]) and return if parts.length > 8
89
96
  condensed_zeros = false
90
97
  parts.each do |part|
91
98
  if part.length == 0
92
- raise ValidationError.new(error_message, fragments, current_schema) if condensed_zeros
99
+ validation_error(error_message, fragments, current_schema, options[:record_errors]) and return if condensed_zeros
93
100
  condensed_zeros = true
94
101
  end
95
- raise ValidationError.new(error_message, fragments, current_schema) if part.length > 4
102
+ validation_error(error_message, fragments, current_schema, options[:record_errors]) and return if part.length > 4
96
103
  end
97
104
  else
98
- raise ValidationError.new(error_message, fragments, current_schema)
105
+ validation_error(error_message, fragments, current_schema, options[:record_errors])
106
+ return
99
107
  end
100
108
  end
101
109
  end
@@ -7,14 +7,14 @@ module JSON
7
7
  data.each_with_index do |item,i|
8
8
  schema = JSON::Schema.new(current_schema.schema['items'],current_schema.uri,validator)
9
9
  fragments << i.to_s
10
- schema.validate(item,fragments)
10
+ schema.validate(item,fragments, options)
11
11
  fragments.pop
12
12
  end
13
13
  elsif current_schema.schema['items'].is_a?(Array)
14
14
  current_schema.schema['items'].each_with_index do |item_schema,i|
15
15
  schema = JSON::Schema.new(item_schema,current_schema.uri,validator)
16
16
  fragments << i.to_s
17
- schema.validate(data[i],fragments)
17
+ schema.validate(data[i],fragments, options)
18
18
  fragments.pop
19
19
  end
20
20
  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
- raise ValidationError.new(message, fragments, current_schema)
9
+ validation_error(message, fragments, current_schema, 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
- raise ValidationError.new(message, fragments, current_schema)
9
+ validation_error(message, fragments, current_schema, 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
- raise ValidationError.new(message, fragments, current_schema)
9
+ validation_error(message, fragments, current_schema, 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
- raise ValidationError.new(message, fragments, current_schema)
7
+ validation_error(message, fragments, current_schema, 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
- raise ValidationError.new(message, fragments, current_schema)
8
+ validation_error(message, fragments, current_schema, 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
- raise ValidationError.new(message, fragments, current_schema)
9
+ validation_error(message, fragments, current_schema, 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
- raise ValidationError.new(message, fragments, current_schema)
9
+ validation_error(message, fragments, current_schema, 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
- raise ValidationError.new(message, fragments, current_schema)
7
+ validation_error(message, fragments, current_schema, 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
- raise ValidationError.new(message, fragments, current_schema)
8
+ validation_error(message, fragments, current_schema, 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
- raise ValidationError.new(message, fragments, current_schema)
9
+ validation_error(message, fragments, current_schema, options[:record_errors])
10
10
  end
11
11
  end
12
12
  end
@@ -11,7 +11,7 @@ module JSON
11
11
  if r.match(key)
12
12
  schema = JSON::Schema.new(property_schema,current_schema.uri,validator)
13
13
  fragments << key
14
- schema.validate(data[key],fragments)
14
+ schema.validate(data[key],fragments,options)
15
15
  fragments.pop
16
16
  end
17
17
  end
@@ -6,13 +6,13 @@ 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
- raise ValidationError.new(message, fragments, current_schema)
9
+ validation_error(message, fragments, current_schema, options[:record_errors])
10
10
  end
11
11
 
12
12
  if data.has_key?(property)
13
13
  schema = JSON::Schema.new(property_schema,current_schema.uri,validator)
14
14
  fragments << property
15
- schema.validate(data[property],fragments)
15
+ schema.validate(data[property],fragments,options)
16
16
  fragments.pop
17
17
  end
18
18
  end
@@ -6,13 +6,13 @@ 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
- raise ValidationError.new(message, fragments, current_schema)
9
+ validation_error(message, fragments, current_schema, options[:record_errors])
10
10
  end
11
11
 
12
12
  if data.has_key?(property)
13
13
  schema = JSON::Schema.new(property_schema,current_schema.uri,validator)
14
14
  fragments << property
15
- schema.validate(data[property],fragments)
15
+ schema.validate(data[property],fragments,options)
16
16
  fragments.pop
17
17
  end
18
18
  end
@@ -44,9 +44,10 @@ module JSON
44
44
 
45
45
  # We have the schema finally, build it and validate!
46
46
  schema = JSON::Schema.new(target_schema,temp_uri,validator)
47
- schema.validate(data, fragments)
47
+ schema.validate(data, fragments, options)
48
48
  else
49
- raise ValidationError.new("The referenced schema '#{temp_uri.to_s}' cannot be found", fragments, current_schema)
49
+ message = "The referenced schema '#{temp_uri.to_s}' cannot be found"
50
+ validation_error(message, fragments, current_schema, options[:record_errors])
50
51
  end
51
52
  end
52
53
  end
@@ -42,7 +42,7 @@ module JSON
42
42
  # Validate as a schema
43
43
  schema = JSON::Schema.new(type,current_schema.uri,validator)
44
44
  begin
45
- schema.validate(data,fragments)
45
+ schema.validate(data,fragments,options)
46
46
  valid = true
47
47
  rescue ValidationError
48
48
  # We don't care that these schemas don't validate - we only care that one validated
@@ -57,13 +57,13 @@ module JSON
57
57
  message = "The property '#{build_fragment(fragments)}' matched one or more of the following types:"
58
58
  types.each {|type| message += type.is_a?(String) ? " #{type}," : " (schema)," }
59
59
  message.chop!
60
- raise ValidationError.new(message, fragments, current_schema)
60
+ validation_error(message, fragments, current_schema, options[:record_errors])
61
61
  end
62
62
  elsif !valid
63
63
  message = "The property '#{build_fragment(fragments)}' did not match one or more of the following types:"
64
64
  types.each {|type| message += type.is_a?(String) ? " #{type}," : " (schema)," }
65
65
  message.chop!
66
- raise ValidationError.new(message, fragments, current_schema)
66
+ validation_error(message, fragments, current_schema, options[:record_errors])
67
67
  end
68
68
  end
69
69
  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
- raise ValidationError.new(message, fragments, current_schema)
10
+ validation_error(message, fragments, current_schema, options[:record_errors])
11
11
  end
12
12
  end
13
13
  end
@@ -34,8 +34,8 @@ module JSON
34
34
  end
35
35
  end
36
36
 
37
- def validate(data, fragments)
38
- @validator.validate(self, data, fragments)
37
+ def validate(data, fragments, options = {})
38
+ @validator.validate(self, data, fragments, options)
39
39
  end
40
40
 
41
41
  def base_uri
@@ -32,6 +32,15 @@ module JSON
32
32
  def self.build_fragment(fragments)
33
33
  "#/#{fragments.join('/')}"
34
34
  end
35
+
36
+ def self.validation_error(message, fragments, current_schema, record_errors)
37
+ error = ValidationError.new(message, fragments, current_schema)
38
+ if record_errors
39
+ ::JSON::Validator.validation_error(error.message)
40
+ else
41
+ raise error
42
+ end
43
+ end
35
44
  end
36
45
 
37
46
  class Validator
@@ -55,11 +64,10 @@ module JSON
55
64
  "#{@uri.scheme}://#{uri.host}#{uri.path}"
56
65
  end
57
66
 
58
- def validate(current_schema, data, fragments)
67
+ def validate(current_schema, data, fragments, options = {})
59
68
  current_schema.schema.each do |attr_name,attribute|
60
-
61
69
  if @attributes.has_key?(attr_name.to_s)
62
- @attributes[attr_name.to_s].validate(current_schema, data, fragments, self)
70
+ @attributes[attr_name.to_s].validate(current_schema, data, fragments, self, options)
63
71
  end
64
72
  end
65
73
  data
@@ -75,12 +83,14 @@ module JSON
75
83
  @@default_opts = {
76
84
  :list => false,
77
85
  :version => nil,
78
- :validate_schema => false
86
+ :validate_schema => false,
87
+ :record_errors => false
79
88
  }
80
89
  @@validators = {}
81
90
  @@default_validator = nil
82
91
  @@available_json_backends = []
83
92
  @@json_backend = nil
93
+ @@errors = []
84
94
 
85
95
  def initialize(schema_data, data, opts={})
86
96
  @options = @@default_opts.clone.merge(opts)
@@ -103,6 +113,8 @@ module JSON
103
113
  validator = JSON::Validator.validators["#{u.scheme}://#{u.host}#{u.path}"]
104
114
  @options[:version] = validator
105
115
  end
116
+
117
+ @validation_options = @options[:record_errors] ? {:record_errors => true} : {}
106
118
 
107
119
  # validate the schema, if requested
108
120
  if @options[:validate_schema]
@@ -124,8 +136,10 @@ module JSON
124
136
  # Run a simple true/false validation of data against a schema
125
137
  def validate()
126
138
  begin
127
- @base_schema.validate(@data,[])
139
+ Validator.clear_errors
140
+ @base_schema.validate(@data,[],@validation_options)
128
141
  Validator.clear_cache
142
+ @@errors
129
143
  rescue JSON::Schema::ValidationError
130
144
  Validator.clear_cache
131
145
  raise $!
@@ -246,10 +260,26 @@ module JSON
246
260
  end
247
261
  alias_method 'validate2', 'validate!'
248
262
 
263
+
264
+ def fully_validate(schema, data, opts={})
265
+ opts[:record_errors] = true
266
+ validator = JSON::Validator.new(schema, data, opts)
267
+ validator.validate
268
+ end
269
+
270
+
249
271
  def clear_cache
250
272
  @@schemas = {} if @@cache_schemas == false
251
273
  end
252
274
 
275
+ def clear_errors
276
+ @@errors = []
277
+ end
278
+
279
+ def validation_error(error)
280
+ @@errors.push(error)
281
+ end
282
+
253
283
  def schemas
254
284
  @@schemas
255
285
  end
@@ -0,0 +1,40 @@
1
+ require 'test/unit'
2
+ require File.dirname(__FILE__) + '/../lib/json-schema'
3
+
4
+ class JSONFullValidation < Test::Unit::TestCase
5
+
6
+ def test_full_validation
7
+ if JSON::Validator.json_backend != nil
8
+ data = {"b" => {"a" => 5}}
9
+ schema = {
10
+ "$schema" => "http://json-schema.org/draft-03/schema#",
11
+ "type" => "object",
12
+ "properties" => {
13
+ "b" => {
14
+ "required" => true
15
+ }
16
+ }
17
+ }
18
+
19
+ errors = JSON::Validator.fully_validate(schema,data)
20
+ assert(errors.empty?)
21
+
22
+ data = {"c" => 5}
23
+ schema = {
24
+ "$schema" => "http://json-schema.org/draft-03/schema#",
25
+ "type" => "object",
26
+ "properties" => {
27
+ "b" => {
28
+ "required" => true
29
+ },
30
+ "c" => {
31
+ "type" => "string"
32
+ }
33
+ }
34
+ }
35
+
36
+ errors = JSON::Validator.fully_validate(schema,data)
37
+ assert(errors.length == 2)
38
+ end
39
+ end
40
+ end
metadata CHANGED
@@ -1,23 +1,32 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: json-schema
3
- version: !ruby/object:Gem::Version
4
- version: 0.9.12
5
- prerelease:
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ - 0
9
+ version: 1.0.0
6
10
  platform: ruby
7
- authors:
11
+ authors:
8
12
  - Kenny Hoxworth
9
13
  autorequire:
10
14
  bindir: bin
11
15
  cert_chain: []
12
- date: 2011-12-14 00:00:00.000000000Z
16
+
17
+ date: 2012-01-04 00:00:00 -05:00
18
+ default_executable:
13
19
  dependencies: []
20
+
14
21
  description:
15
22
  email: hoxworth@gmail.com
16
23
  executables: []
24
+
17
25
  extensions: []
18
- extra_rdoc_files:
26
+
27
+ extra_rdoc_files:
19
28
  - README.textile
20
- files:
29
+ files:
21
30
  - lib/json-schema/attributes/additionalitems.rb
22
31
  - lib/json-schema/attributes/additionalproperties.rb
23
32
  - lib/json-schema/attributes/dependencies.rb
@@ -55,43 +64,40 @@ files:
55
64
  - resources/draft-02.json
56
65
  - resources/draft-03.json
57
66
  - README.textile
58
- - test/test_extended_schema.rb
59
- - test/test_files.rb
60
- - test/test_jsonschema_draft1.rb
61
- - test/test_jsonschema_draft2.rb
62
- - test/test_jsonschema_draft3.rb
63
- - test/test_schema_validation.rb
64
- - test/data/bad_data_1.json
65
- - test/data/good_data_1.json
66
- - test/schemas/good_schema_1.json
67
- - test/schemas/good_schema_2.json
67
+ has_rdoc: true
68
68
  homepage: http://github.com/hoxworth/json-schema/tree/master
69
69
  licenses: []
70
+
70
71
  post_install_message:
71
72
  rdoc_options: []
72
- require_paths:
73
+
74
+ require_paths:
73
75
  - lib
74
- required_ruby_version: !ruby/object:Gem::Requirement
75
- none: false
76
- requirements:
77
- - - ! '>='
78
- - !ruby/object:Gem::Version
79
- version: '0'
80
- required_rubygems_version: !ruby/object:Gem::Requirement
81
- none: false
82
- requirements:
83
- - - ! '>='
84
- - !ruby/object:Gem::Version
85
- version: '0'
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ segments:
88
+ - 0
89
+ version: "0"
86
90
  requirements: []
91
+
87
92
  rubyforge_project:
88
- rubygems_version: 1.8.10
93
+ rubygems_version: 1.3.6
89
94
  signing_key:
90
95
  specification_version: 3
91
96
  summary: Ruby JSON Schema Validator
92
- test_files:
97
+ test_files:
93
98
  - test/test_extended_schema.rb
94
99
  - test/test_files.rb
100
+ - test/test_full_validation.rb
95
101
  - test/test_jsonschema_draft1.rb
96
102
  - test/test_jsonschema_draft2.rb
97
103
  - test/test_jsonschema_draft3.rb