json-schema 2.8.1 → 4.1.1

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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +54 -10
  3. data/lib/json-schema/attribute.rb +13 -14
  4. data/lib/json-schema/attributes/additionalitems.rb +1 -0
  5. data/lib/json-schema/attributes/additionalproperties.rb +3 -6
  6. data/lib/json-schema/attributes/allof.rb +6 -4
  7. data/lib/json-schema/attributes/anyof.rb +2 -2
  8. data/lib/json-schema/attributes/const.rb +15 -0
  9. data/lib/json-schema/attributes/dependencies.rb +1 -0
  10. data/lib/json-schema/attributes/disallow.rb +2 -1
  11. data/lib/json-schema/attributes/enum.rb +2 -2
  12. data/lib/json-schema/attributes/extends.rb +6 -6
  13. data/lib/json-schema/attributes/format.rb +2 -1
  14. data/lib/json-schema/attributes/formats/date.rb +1 -0
  15. data/lib/json-schema/attributes/formats/date_time.rb +2 -1
  16. data/lib/json-schema/attributes/formats/date_time_v4.rb +1 -0
  17. data/lib/json-schema/attributes/formats/ip.rb +1 -1
  18. data/lib/json-schema/attributes/formats/uri.rb +1 -0
  19. data/lib/json-schema/attributes/items.rb +1 -0
  20. data/lib/json-schema/attributes/limits/numeric.rb +1 -1
  21. data/lib/json-schema/attributes/maxdecimal.rb +1 -1
  22. data/lib/json-schema/attributes/not.rb +2 -2
  23. data/lib/json-schema/attributes/oneof.rb +2 -4
  24. data/lib/json-schema/attributes/patternproperties.rb +1 -0
  25. data/lib/json-schema/attributes/properties.rb +7 -7
  26. data/lib/json-schema/attributes/properties_v4.rb +1 -1
  27. data/lib/json-schema/attributes/propertynames.rb +23 -0
  28. data/lib/json-schema/attributes/ref.rb +7 -7
  29. data/lib/json-schema/attributes/required.rb +3 -2
  30. data/lib/json-schema/attributes/type.rb +3 -2
  31. data/lib/json-schema/attributes/type_v4.rb +1 -1
  32. data/lib/json-schema/errors/validation_error.rb +4 -5
  33. data/lib/json-schema/schema/reader.rb +3 -1
  34. data/lib/json-schema/schema/validator.rb +3 -3
  35. data/lib/json-schema/schema.rb +3 -4
  36. data/lib/json-schema/util/array_set.rb +1 -1
  37. data/lib/json-schema/util/uri.rb +7 -7
  38. data/lib/json-schema/util/uuid.rb +227 -226
  39. data/lib/json-schema/validator.rb +119 -114
  40. data/lib/json-schema/validators/draft1.rb +21 -23
  41. data/lib/json-schema/validators/draft2.rb +22 -24
  42. data/lib/json-schema/validators/draft3.rb +26 -28
  43. data/lib/json-schema/validators/draft4.rb +34 -36
  44. data/lib/json-schema/validators/draft6.rb +36 -36
  45. data/lib/json-schema/validators/hyper-draft1.rb +2 -3
  46. data/lib/json-schema/validators/hyper-draft2.rb +2 -3
  47. data/lib/json-schema/validators/hyper-draft3.rb +2 -3
  48. data/lib/json-schema/validators/hyper-draft4.rb +2 -3
  49. data/lib/json-schema/validators/hyper-draft6.rb +2 -3
  50. data/lib/json-schema.rb +2 -2
  51. data/resources/draft-06.json +12 -12
  52. metadata +15 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3361b9ea49eb9e208babcec94973eb5efd0d371c2a2cbab16cca9e6555b11b77
4
- data.tar.gz: 82f4c4d50b75db5d379555c76ca2606580c14d74a0ec5088504cfb5f5025e1ed
3
+ metadata.gz: 6b6a5072f20570ae4262df13648a1b637b5db2c02cf881c2728277ea5a203f6d
4
+ data.tar.gz: 4b92633224b1338d58918e7a2d2f5d3e117fee03409455d6f47ea51c8bef7b18
5
5
  SHA512:
6
- metadata.gz: 5040893a974d35c4e9833076d8db0073215fdc6330535a4ae7c7d3eef3bdfd902e3642ed5bd9729735b65d8821e30db2b563411d4fd6cf0187c6efe2a4179669
7
- data.tar.gz: 9161d768e8829faafefeabf7723c462019831393d4c696ccbc9b7f7be9f5affcc988cf93a2ce1709ea1b6cddd70230fa44815cd4a3e965b7c15ea65b2b0c3de2
6
+ metadata.gz: 9b5301a03a3fb7d3a43c275858df22d41cface2a465ff2fcfda28c9528f491e6a8f302fbbf52232de68e31d6a32540b9ad8a392fab82ec2b2113980e83119b72
7
+ data.tar.gz: 16f57a870e6b75280f5376d57785ad94500cbfd50bc3ea9ba01df486d0938c36907114780bacfc4860359e73d7adf87ce5c73205ef52ebea1f829b64d7630906
data/README.md CHANGED
@@ -1,13 +1,16 @@
1
- [![Gem Version](https://badge.fury.io/rb/json-schema.svg)](https://badge.fury.io/rb/json-schema)
2
- [![Travis](https://travis-ci.org/ruby-json-schema/json-schema.svg?branch=master)](https://travis-ci.org/ruby-json-schema/json-schema)
3
- [![Code Climate](https://codeclimate.com/github/ruby-json-schema/json-schema/badges/gpa.svg)](https://codeclimate.com/github/ruby-json-schema/json-schema)
1
+ # Ruby JSON Schema Validator
4
2
 
5
- Ruby JSON Schema Validator
6
- ==========================
3
+ [![License](https://img.shields.io/github/license/voxpupuli/json-schema.svg)](https://github.com/voxpupuli/json-schema/blob/master/LICENSE)
4
+ [![Test](https://github.com/voxpupuli/json-schema/actions/workflows/test.yml/badge.svg)](https://github.com/voxpupuli/json-schema/actions/workflows/test.yml)
5
+ [![Release](https://github.com/voxpupuli/json-schema/actions/workflows/release.yml/badge.svg)](https://github.com/voxpupuli/json-schema/actions/workflows/release.yml)
6
+ [![RubyGem Version](https://img.shields.io/gem/v/json-schema.svg)](https://rubygems.org/gems/json-schema)
7
+ [![RubyGem Downloads](https://img.shields.io/gem/dt/json-schema.svg)](https://rubygems.org/gems/json-schema)
8
+ [![Donated by Iain Beeston](https://img.shields.io/badge/donated%20by-Iain%20Beeston-fb7047.svg)](#transfer-notice)
7
9
 
8
10
  This library is intended to provide Ruby with an interface for validating JSON
9
11
  objects against a JSON schema conforming to [JSON Schema Draft
10
- 4](http://tools.ietf.org/html/draft-zyp-json-schema-04). Legacy support for
12
+ 6](https://tools.ietf.org/html/draft-wright-json-schema-01). Legacy support for
13
+ [JSON Schema Draft 4](http://tools.ietf.org/html/draft-zyp-json-schema-04),
11
14
  [JSON Schema Draft 3](http://tools.ietf.org/html/draft-zyp-json-schema-03),
12
15
  [JSON Schema Draft 2](http://tools.ietf.org/html/draft-zyp-json-schema-02), and
13
16
  [JSON Schema Draft 1](http://tools.ietf.org/html/draft-zyp-json-schema-01) is
@@ -17,7 +20,7 @@ Additional Resources
17
20
  --------------------
18
21
 
19
22
  - [Google Groups](https://groups.google.com/forum/#!forum/ruby-json-schema)
20
- - #ruby-json-schema on chat.freenode.net
23
+ - #voxpupuli on irc.libera.chat
21
24
 
22
25
  Version 2.0.0 Upgrade Notes
23
26
  ---------------------------
@@ -27,6 +30,14 @@ default**, so schemas that do not declare a validator using the `$schema`
27
30
  keyword will use Draft-04 now instead of Draft-03. This is the reason for the
28
31
  major version upgrade.
29
32
 
33
+ Version 3.0.0 Upgrade Notes
34
+ ---------------------------
35
+
36
+ All individual changes are documented in the CHANGELOG.md. The biggest change
37
+ is that the new version only supports Ruby 2.5 and newer. Take a look into the
38
+ gemspec file to see the currently supported Ruby version and also
39
+ `.github/workflows/test.yml` to see the Ruby versions we test on.
40
+
30
41
  Installation
31
42
  ------------
32
43
 
@@ -39,8 +50,8 @@ gem install json-schema
39
50
  From the git repo:
40
51
 
41
52
  ```sh
42
- $ gem build json-schema.gemspec
43
- $ gem install json-schema-2.5.2.gem
53
+ gem build json-schema.gemspec
54
+ gem install json-schema-*.gem
44
55
  ```
45
56
 
46
57
  Validation
@@ -166,7 +177,7 @@ JSON::Validator.validate(schema, [{"a" => 1}, {"a" => 2}, {"a" => 3}])
166
177
  JSON::Validator.fully_validate(schema, { "a" => "taco" }, :errors_as_objects => true)
167
178
 
168
179
  #
169
- # with the `:strict` option, all properties are condisidered to have `"required": true` and all objects `"additionalProperties": false`
180
+ # with the `:strict` option, all properties are considered to have `"required": true` and all objects `"additionalProperties": false`
170
181
  #
171
182
 
172
183
  # => true
@@ -230,6 +241,19 @@ JSON::Validator.validate(schema, { "a" => 1 }, :parse_data => false)
230
241
  # => false
231
242
  JSON::Validator.validate(schema, '{ "a": 1 }', :parse_data => false)
232
243
 
244
+ #
245
+ # with the `:parse_integer` option set to false, the integer value given as string will not be parsed.
246
+ #
247
+
248
+ # => true
249
+ JSON::Validator.validate({type: "integer"}, "23")
250
+ # => false
251
+ JSON::Validator.validate({type: "integer"}, "23", parse_integer: false)
252
+ # => true
253
+ JSON::Validator.validate({type: "string"}, "123", parse_integer: false)
254
+ # => false
255
+ JSON::Validator.validate({type: "string"}, "123")
256
+
233
257
  #
234
258
  # with the `:json` option, the json must be an unparsed json text (not a hash, a uri or a file path)
235
259
  #
@@ -472,3 +496,23 @@ value is of the correct datatype (e.g., an instance value is validated to be an
472
496
  integer or a float in the case of 'utc-millisec').
473
497
 
474
498
  Additionally, JSON::Validator does not handle any json hyperschema attributes.
499
+
500
+ # Transfer Notice
501
+
502
+ This plugin was originally authored by [Iain Beeston](https://github.com/iainbeeston).
503
+ The maintainer preferred that [Vox Pupuli](https://voxpupuli.org/) take ownership of the module for future improvement and maintenance.
504
+ Existing pull requests and issues were transferred, please fork and continue to contribute [here](https://github.com/voxpupuli/json-schema).
505
+
506
+ # License
507
+
508
+ This gem is licensed unter the [MIT license](LICENSE.md).
509
+
510
+ ## Release information
511
+
512
+ To make a new release, please do:
513
+ * update the version in VERSION.yml
514
+ * Install gems with `bundle install --with release --path .vendor`
515
+ * generate the changelog with `bundle exec rake changelog`
516
+ * Check if the new version matches the closed issues/PRs in the changelog
517
+ * Create a PR with it
518
+ * After it got merged, push a tag. GitHub actions will do the actual release to rubygems and GitHub Packages
@@ -3,8 +3,7 @@ require 'json-schema/errors/validation_error'
3
3
  module JSON
4
4
  class Schema
5
5
  class Attribute
6
- def self.validate(current_schema, data, fragments, processor, validator, options = {})
7
- end
6
+ def self.validate(current_schema, data, fragments, processor, validator, options = {}); end
8
7
 
9
8
  def self.build_fragment(fragments)
10
9
  "#/#{fragments.join('/')}"
@@ -24,14 +23,14 @@ module JSON
24
23
  end
25
24
 
26
25
  TYPE_CLASS_MAPPINGS = {
27
- "string" => String,
28
- "number" => Numeric,
29
- "integer" => Integer,
30
- "boolean" => [TrueClass, FalseClass],
31
- "object" => Hash,
32
- "array" => Array,
33
- "null" => NilClass,
34
- "any" => Object
26
+ 'string' => String,
27
+ 'number' => Numeric,
28
+ 'integer' => Integer,
29
+ 'boolean' => [TrueClass, FalseClass],
30
+ 'object' => Hash,
31
+ 'array' => Array,
32
+ 'null' => NilClass,
33
+ 'any' => Object,
35
34
  }
36
35
 
37
36
  def self.data_valid_for_type?(data, type)
@@ -41,11 +40,11 @@ module JSON
41
40
 
42
41
  # Lookup Schema type of given class instance
43
42
  def self.type_of_data(data)
44
- type, _ = TYPE_CLASS_MAPPINGS.map { |k,v| [k,v] }.sort_by { |(_, v)|
43
+ type, = TYPE_CLASS_MAPPINGS.map { |k, v| [k, v] }.sort_by do |(_, v)|
45
44
  -Array(v).map { |klass| klass.ancestors.size }.max
46
- }.find { |(_, v)|
47
- Array(v).any? { |klass| data.kind_of?(klass) }
48
- }
45
+ end.find do |(_, v)|
46
+ Array(v).any? { |klass| data.is_a?(klass) }
47
+ end
49
48
  type
50
49
  end
51
50
  end
@@ -19,6 +19,7 @@ module JSON
19
19
  additional_items_schema = JSON::Schema.new(schema['additionalItems'], current_schema.uri, validator)
20
20
  data.each_with_index do |item, i|
21
21
  next if i < schema['items'].length
22
+
22
23
  additional_items_schema.validate(item, fragments + [i.to_s], processor, options)
23
24
  end
24
25
  end
@@ -33,11 +33,9 @@ module JSON
33
33
  extra_properties = extra_properties - schema['properties'].keys
34
34
  end
35
35
 
36
- if schema['patternProperties']
37
- schema['patternProperties'].each_key do |key|
38
- regexp = Regexp.new(key)
39
- extra_properties.reject! { |prop| regexp.match(prop) }
40
- end
36
+ schema['patternProperties']&.each_key do |key|
37
+ regexp = Regexp.new(key)
38
+ extra_properties.reject! { |prop| regexp.match(prop) }
41
39
  end
42
40
 
43
41
  if extended_schemas = schema['extends']
@@ -52,7 +50,6 @@ module JSON
52
50
 
53
51
  extra_properties
54
52
  end
55
-
56
53
  end
57
54
  end
58
55
  end
@@ -7,18 +7,20 @@ module JSON
7
7
  # Create an hash to hold errors that are generated during validation
8
8
  errors = Hash.new { |hsh, k| hsh[k] = [] }
9
9
  valid = true
10
+ message = nil
10
11
 
11
12
  current_schema.schema['allOf'].each_with_index do |element, schema_index|
12
- schema = JSON::Schema.new(element,current_schema.uri,validator)
13
+ schema = JSON::Schema.new(element, current_schema.uri, validator)
13
14
 
14
15
  # We're going to add a little cruft here to try and maintain any validation errors that occur in the allOf
15
16
  # We'll handle this by keeping an error count before and after validation, extracting those errors and pushing them onto an error array
16
17
  pre_validation_error_count = validation_errors(processor).count
17
18
 
18
19
  begin
19
- schema.validate(data,fragments,processor,options)
20
- rescue ValidationError
20
+ schema.validate(data, fragments, processor, options)
21
+ rescue ValidationError => e
21
22
  valid = false
23
+ message = e.message
22
24
  end
23
25
 
24
26
  diff = validation_errors(processor).count - pre_validation_error_count
@@ -29,7 +31,7 @@ module JSON
29
31
  end
30
32
 
31
33
  if !valid || !errors.empty?
32
- message = "The property '#{build_fragment(fragments)}' of type #{type_of_data(data)} did not match all of the required schemas"
34
+ message ||= "The property '#{build_fragment(fragments)}' of type #{type_of_data(data)} did not match all of the required schemas"
33
35
  validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
34
36
  validation_errors(processor).last.sub_errors = errors
35
37
  end
@@ -11,14 +11,14 @@ module JSON
11
11
  original_data = data.is_a?(Hash) ? data.clone : data
12
12
 
13
13
  current_schema.schema['anyOf'].each_with_index do |element, schema_index|
14
- schema = JSON::Schema.new(element,current_schema.uri,validator)
14
+ schema = JSON::Schema.new(element, current_schema.uri, validator)
15
15
 
16
16
  # We're going to add a little cruft here to try and maintain any validation errors that occur in the anyOf
17
17
  # We'll handle this by keeping an error count before and after validation, extracting those errors and pushing them onto a union error
18
18
  pre_validation_error_count = validation_errors(processor).count
19
19
 
20
20
  begin
21
- schema.validate(data,fragments,processor,options)
21
+ schema.validate(data, fragments, processor, options)
22
22
  valid = true
23
23
  rescue ValidationError
24
24
  # We don't care that these schemas don't validate - we only care that one validated
@@ -0,0 +1,15 @@
1
+ require 'json-schema/attribute'
2
+
3
+ module JSON
4
+ class Schema
5
+ class ConstAttribute < Attribute
6
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
7
+ const_value = current_schema.schema['const']
8
+ unless const_value == data
9
+ message = "The property '#{build_fragment(fragments)}' value #{data.inspect} did not match constant '#{const_value}'"
10
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -26,6 +26,7 @@ module JSON
26
26
 
27
27
  def self.validate_dependency(schema, data, property, value, fragments, processor, attribute, options)
28
28
  return if data.key?(value.to_s)
29
+
29
30
  message = "The property '#{build_fragment(fragments)}' has a property '#{property}' that depends on a missing property '#{value}'"
30
31
  validation_error(processor, message, fragments, schema, attribute, options[:record_errors])
31
32
  end
@@ -5,7 +5,8 @@ module JSON
5
5
  class DisallowAttribute < Attribute
6
6
  def self.validate(current_schema, data, fragments, processor, validator, options = {})
7
7
  return unless type = validator.attributes['type']
8
- type.validate(current_schema, data, fragments, processor, validator, options.merge(:disallow => true))
8
+
9
+ type.validate(current_schema, data, fragments, processor, validator, options.merge(disallow: true))
9
10
  end
10
11
  end
11
12
  end
@@ -7,14 +7,14 @@ module JSON
7
7
  enum = current_schema.schema['enum']
8
8
  return if enum.include?(data)
9
9
 
10
- values = enum.map { |val|
10
+ values = enum.map do |val|
11
11
  case val
12
12
  when nil then 'null'
13
13
  when Array then 'array'
14
14
  when Hash then 'object'
15
15
  else val.to_s
16
16
  end
17
- }.join(', ')
17
+ end.join(', ')
18
18
 
19
19
  message = "The property '#{build_fragment(fragments)}' value #{data.inspect} did not match one of the following values: #{values}"
20
20
  validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
@@ -8,7 +8,7 @@ module JSON
8
8
  schemas = current_schema.schema['extends']
9
9
  schemas = [schemas] if !schemas.is_a?(Array)
10
10
  schemas.each do |s|
11
- uri,schema = get_extended_uri_and_schema(s, current_schema, validator)
11
+ uri, schema = get_extended_uri_and_schema(s, current_schema, validator)
12
12
  if schema
13
13
  schema.validate(data, fragments, processor, options)
14
14
  elsif uri
@@ -22,15 +22,15 @@ module JSON
22
22
  end
23
23
 
24
24
  def self.get_extended_uri_and_schema(s, current_schema, validator)
25
- uri,schema = nil,nil
25
+ uri, schema = nil, nil
26
26
 
27
27
  if s.is_a?(Hash)
28
28
  uri = current_schema.uri
29
29
  if s['$ref']
30
- ref_uri,ref_schema = JSON::Schema::RefAttribute.get_referenced_uri_and_schema(s, current_schema, validator)
30
+ ref_uri, ref_schema = JSON::Schema::RefAttribute.get_referenced_uri_and_schema(s, current_schema, validator)
31
31
  if ref_schema
32
32
  if s.size == 1 # Check if anything else apart from $ref
33
- uri,schema = ref_uri,ref_schema
33
+ uri, schema = ref_uri, ref_schema
34
34
  else
35
35
  s = s.dup
36
36
  s.delete '$ref'
@@ -38,10 +38,10 @@ module JSON
38
38
  end
39
39
  end
40
40
  end
41
- schema ||= JSON::Schema.new(s,uri,validator)
41
+ schema ||= JSON::Schema.new(s, uri, validator)
42
42
  end
43
43
 
44
- [uri,schema]
44
+ [uri, schema]
45
45
  end
46
46
  end
47
47
  end
@@ -5,9 +5,10 @@ module JSON
5
5
  class FormatAttribute < Attribute
6
6
  def self.validate(current_schema, data, fragments, processor, validator, options = {})
7
7
  return unless data_valid_for_type?(data, current_schema.schema['type'])
8
+
8
9
  format = current_schema.schema['format'].to_s
9
10
  validator = validator.formats[format]
10
- validator.validate(current_schema, data, fragments, processor, validator, options) unless validator.nil?
11
+ validator&.validate(current_schema, data, fragments, processor, validator, options)
11
12
  end
12
13
  end
13
14
  end
@@ -13,6 +13,7 @@ module JSON
13
13
  Date.parse(data)
14
14
  rescue ArgumentError => e
15
15
  raise e unless e.message == 'invalid date'
16
+
16
17
  validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
17
18
  end
18
19
  else
@@ -10,12 +10,13 @@ module JSON
10
10
  if data.is_a?(String)
11
11
  error_message = "The property '#{build_fragment(fragments)}' must be a date/time in the ISO-8601 format of YYYY-MM-DDThh:mm:ssZ or YYYY-MM-DDThh:mm:ss.ssZ"
12
12
  if (m = REGEXP.match(data))
13
- parts = data.split("T")
13
+ parts = data.split('T')
14
14
 
15
15
  begin
16
16
  Date.parse(parts[0])
17
17
  rescue ArgumentError => e
18
18
  raise e unless e.message == 'invalid date'
19
+
19
20
  validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
20
21
  return
21
22
  end
@@ -5,6 +5,7 @@ module JSON
5
5
  class DateTimeV4Format < FormatAttribute
6
6
  def self.validate(current_schema, data, fragments, processor, validator, options = {})
7
7
  return unless data.is_a?(String)
8
+
8
9
  DateTime.rfc3339(data)
9
10
  rescue ArgumentError
10
11
  error_message = "The property '#{build_fragment(fragments)}' must be a valid RFC3339 date/time string"
@@ -11,7 +11,7 @@ module JSON
11
11
  begin
12
12
  ip = IPAddr.new(data)
13
13
  rescue ArgumentError => e
14
- raise e unless e.message == 'invalid address'
14
+ raise e unless e.message.start_with?('invalid address')
15
15
  end
16
16
 
17
17
  family = ip_version == 6 ? Socket::AF_INET6 : Socket::AF_INET
@@ -6,6 +6,7 @@ module JSON
6
6
  class UriFormat < FormatAttribute
7
7
  def self.validate(current_schema, data, fragments, processor, validator, options = {})
8
8
  return unless data.is_a?(String)
9
+
9
10
  error_message = "The property '#{build_fragment(fragments)}' must be a valid URI"
10
11
  begin
11
12
  JSON::Util::URI.parse(data)
@@ -17,6 +17,7 @@ module JSON
17
17
  when Array
18
18
  items.each_with_index do |item_schema, i|
19
19
  break if i >= data.length
20
+
20
21
  schema = JSON::Schema.new(item_schema, current_schema.uri, validator)
21
22
  schema.validate(data[i], fragments + [i.to_s], processor, options)
22
23
  end
@@ -9,7 +9,7 @@ module JSON
9
9
 
10
10
  def self.error_message(schema)
11
11
  exclusivity = exclusive?(schema) ? 'exclusively' : 'inclusively'
12
- format("did not have a %s value of %s, %s", limit_name, limit(schema), exclusivity)
12
+ format('did not have a %s value of %s, %s', limit_name, limit(schema), exclusivity)
13
13
  end
14
14
  end
15
15
  end
@@ -7,7 +7,7 @@ module JSON
7
7
  return unless data.is_a?(Numeric)
8
8
 
9
9
  max_decimal_places = current_schema.schema['maxDecimal']
10
- s = data.to_s.split(".")[1]
10
+ s = data.to_s.split('.')[1]
11
11
  if s && s.length > max_decimal_places
12
12
  message = "The property '#{build_fragment(fragments)}' had more decimal places than the allowed #{max_decimal_places}"
13
13
  validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
@@ -4,12 +4,12 @@ module JSON
4
4
  class Schema
5
5
  class NotAttribute < Attribute
6
6
  def self.validate(current_schema, data, fragments, processor, validator, options = {})
7
- schema = JSON::Schema.new(current_schema.schema['not'],current_schema.uri,validator)
7
+ schema = JSON::Schema.new(current_schema.schema['not'], current_schema.uri, validator)
8
8
  failed = true
9
9
  errors_copy = processor.validation_errors.clone
10
10
 
11
11
  begin
12
- schema.validate(data,fragments,processor,options)
12
+ schema.validate(data, fragments, processor, options)
13
13
  # If we're recording errors, we don't throw an exception. Instead, check the errors array length
14
14
  if options[:record_errors] && errors_copy.length != processor.validation_errors.length
15
15
  processor.validation_errors.replace(errors_copy)
@@ -15,10 +15,10 @@ module JSON
15
15
  valid = false
16
16
 
17
17
  one_of.each_with_index do |element, schema_index|
18
- schema = JSON::Schema.new(element,current_schema.uri,validator)
18
+ schema = JSON::Schema.new(element, current_schema.uri, validator)
19
19
  pre_validation_error_count = validation_errors(processor).count
20
20
  begin
21
- schema.validate(data,fragments,processor,options)
21
+ schema.validate(data, fragments, processor, options)
22
22
  success_data = data.is_a?(Hash) ? data.clone : data
23
23
  valid = true
24
24
  rescue ValidationError
@@ -35,8 +35,6 @@ module JSON
35
35
  data = original_data
36
36
  end
37
37
 
38
-
39
-
40
38
  if validation_error_count == one_of.length - 1
41
39
  data = success_data
42
40
  return
@@ -12,6 +12,7 @@ module JSON
12
12
  # Check each key in the data hash to see if it matches the regex
13
13
  data.each do |key, value|
14
14
  next unless regexp.match(key)
15
+
15
16
  schema = JSON::Schema.new(property_schema, current_schema.uri, validator)
16
17
  schema.validate(data[key], fragments + [key], processor, options)
17
18
  end
@@ -4,7 +4,7 @@ module JSON
4
4
  class Schema
5
5
  class PropertiesAttribute < Attribute
6
6
  def self.required?(schema, options)
7
- schema.fetch('required') { options[:strict] }
7
+ schema.fetch('required') { options[:allPropertiesRequired] }
8
8
  end
9
9
 
10
10
  def self.validate(current_schema, data, fragments, processor, validator, options = {})
@@ -15,9 +15,9 @@ module JSON
15
15
  property = property.to_s
16
16
 
17
17
  if !data.key?(property) &&
18
- options[:insert_defaults] &&
19
- property_schema.has_key?('default') &&
20
- !property_schema['readonly']
18
+ options[:insert_defaults] &&
19
+ property_schema.has_key?('default') &&
20
+ !property_schema['readonly']
21
21
  default = property_schema['default']
22
22
  data[property] = default.is_a?(Hash) ? default.clone : default
23
23
  end
@@ -33,8 +33,8 @@ module JSON
33
33
  end
34
34
  end
35
35
 
36
- # When strict is true, ensure no undefined properties exist in the data
37
- return unless options[:strict] == true && !schema.key?('additionalProperties')
36
+ # When noAdditionalProperties is true, ensure no undefined properties exist in the data
37
+ return unless options[:noAdditionalProperties] == true && !schema.key?('additionalProperties')
38
38
 
39
39
  diff = data.select do |k, v|
40
40
  k = k.to_s
@@ -55,7 +55,7 @@ module JSON
55
55
  end
56
56
  end
57
57
 
58
- if diff.size > 0
58
+ unless diff.empty?
59
59
  properties = diff.keys.join(', ')
60
60
  message = "The property '#{build_fragment(fragments)}' contained undefined properties: '#{properties}'"
61
61
  validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
@@ -6,7 +6,7 @@ module JSON
6
6
  # draft4 relies on its own RequiredAttribute validation at a higher level, rather than
7
7
  # as an attribute of individual properties.
8
8
  def self.required?(schema, options)
9
- options[:strict] == true
9
+ options[:allPropertiesRequired] == true
10
10
  end
11
11
  end
12
12
  end
@@ -0,0 +1,23 @@
1
+ require 'json-schema/attribute'
2
+
3
+ module JSON
4
+ class Schema
5
+ class PropertyNames < Attribute
6
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
7
+ return unless data.is_a?(Hash)
8
+
9
+ propnames = current_schema.schema['propertyNames']
10
+
11
+ if propnames.is_a?(Hash)
12
+ schema = JSON::Schema.new(propnames, current_schema.uri, validator)
13
+ data.each_key do |key|
14
+ schema.validate(key, fragments + [key], processor, options)
15
+ end
16
+ elsif propnames == false && data.any?
17
+ message = "The property '#{build_fragment(fragments)}' contains additional properties #{data.keys.inspect} outside of the schema when none are allowed"
18
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -6,7 +6,7 @@ module JSON
6
6
  class Schema
7
7
  class RefAttribute < Attribute
8
8
  def self.validate(current_schema, data, fragments, processor, validator, options = {})
9
- uri,schema = get_referenced_uri_and_schema(current_schema.schema, current_schema, validator)
9
+ uri, schema = get_referenced_uri_and_schema(current_schema.schema, current_schema, validator)
10
10
 
11
11
  if schema
12
12
  schema.validate(data, fragments, processor, options)
@@ -20,19 +20,19 @@ module JSON
20
20
  end
21
21
 
22
22
  def self.get_referenced_uri_and_schema(s, current_schema, validator)
23
- uri,schema = nil,nil
23
+ uri, schema = nil, nil
24
24
 
25
25
  temp_uri = JSON::Util::URI.normalize_ref(s['$ref'], current_schema.uri)
26
26
 
27
27
  # Grab the parent schema from the schema list
28
- schema_key = temp_uri.to_s.split("#")[0] + "#"
28
+ schema_key = temp_uri.to_s.split('#')[0] + '#'
29
29
 
30
30
  ref_schema = JSON::Validator.schema_for_uri(schema_key)
31
31
 
32
32
  if ref_schema
33
33
  # Perform fragment resolution to retrieve the appropriate level for the schema
34
34
  target_schema = ref_schema.schema
35
- fragments = JSON::Util::URI.parse(JSON::Util::URI.unescape_uri(temp_uri)).fragment.split("/")
35
+ fragments = JSON::Util::URI.parse(JSON::Util::URI.unescape_uri(temp_uri)).fragment.split('/')
36
36
  fragment_path = ''
37
37
  fragments.each do |fragment|
38
38
  if fragment && fragment != ''
@@ -44,17 +44,17 @@ module JSON
44
44
  end
45
45
  fragment_path = fragment_path + "/#{fragment}"
46
46
  if target_schema.nil?
47
- raise SchemaError.new("The fragment '#{fragment_path}' does not exist on schema #{ref_schema.uri.to_s}")
47
+ raise SchemaError, "The fragment '#{fragment_path}' does not exist on schema #{ref_schema.uri.to_s}"
48
48
  end
49
49
  end
50
50
  end
51
51
 
52
52
  # We have the schema finally, build it and validate!
53
53
  uri = temp_uri
54
- schema = JSON::Schema.new(target_schema,temp_uri,validator)
54
+ schema = JSON::Schema.new(target_schema, temp_uri, validator)
55
55
  end
56
56
 
57
- [uri,schema]
57
+ [uri, schema]
58
58
  end
59
59
  end
60
60
  end
@@ -11,11 +11,12 @@ module JSON
11
11
 
12
12
  schema['required'].each do |property, property_schema|
13
13
  next if data.has_key?(property.to_s)
14
+
14
15
  prop_defaults = options[:insert_defaults] &&
15
16
  defined_properties &&
16
17
  defined_properties[property] &&
17
- !defined_properties[property]["default"].nil? &&
18
- !defined_properties[property]["readonly"]
18
+ !defined_properties[property]['default'].nil? &&
19
+ !defined_properties[property]['readonly']
19
20
 
20
21
  if !prop_defaults
21
22
  message = "The property '#{build_fragment(fragments)}' did not contain a required property of '#{property}'"