json-schema 2.8.1 → 6.1.0

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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +55 -11
  3. data/lib/json-schema/attribute.rb +15 -16
  4. data/lib/json-schema/attributes/additionalitems.rb +1 -0
  5. data/lib/json-schema/attributes/additionalproperties.rb +4 -7
  6. data/lib/json-schema/attributes/allof.rb +33 -6
  7. data/lib/json-schema/attributes/anyof.rb +4 -4
  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/divisibleby.rb +1 -1
  12. data/lib/json-schema/attributes/enum.rb +3 -3
  13. data/lib/json-schema/attributes/extends.rb +10 -8
  14. data/lib/json-schema/attributes/format.rb +2 -1
  15. data/lib/json-schema/attributes/formats/custom.rb +5 -7
  16. data/lib/json-schema/attributes/formats/date.rb +2 -1
  17. data/lib/json-schema/attributes/formats/date_time.rb +4 -3
  18. data/lib/json-schema/attributes/formats/date_time_v4.rb +2 -1
  19. data/lib/json-schema/attributes/formats/ip.rb +3 -3
  20. data/lib/json-schema/attributes/formats/time.rb +1 -1
  21. data/lib/json-schema/attributes/formats/uri.rb +2 -1
  22. data/lib/json-schema/attributes/items.rb +1 -0
  23. data/lib/json-schema/attributes/limit.rb +2 -2
  24. data/lib/json-schema/attributes/limits/numeric.rb +1 -1
  25. data/lib/json-schema/attributes/maxdecimal.rb +2 -2
  26. data/lib/json-schema/attributes/not.rb +2 -2
  27. data/lib/json-schema/attributes/oneof.rb +9 -11
  28. data/lib/json-schema/attributes/pattern.rb +1 -1
  29. data/lib/json-schema/attributes/patternproperties.rb +2 -1
  30. data/lib/json-schema/attributes/properties.rb +10 -10
  31. data/lib/json-schema/attributes/properties_v4.rb +2 -2
  32. data/lib/json-schema/attributes/propertynames.rb +23 -0
  33. data/lib/json-schema/attributes/ref.rb +19 -18
  34. data/lib/json-schema/attributes/required.rb +6 -5
  35. data/lib/json-schema/attributes/type.rb +11 -10
  36. data/lib/json-schema/attributes/type_v4.rb +3 -3
  37. data/lib/json-schema/attributes/uniqueitems.rb +1 -1
  38. data/lib/json-schema/errors/validation_error.rb +10 -10
  39. data/lib/json-schema/schema/reader.rb +4 -2
  40. data/lib/json-schema/schema/validator.rb +4 -4
  41. data/lib/json-schema/schema.rb +13 -14
  42. data/lib/json-schema/util/array_set.rb +2 -4
  43. data/lib/json-schema/util/uri.rb +100 -77
  44. data/lib/json-schema/util/uuid.rb +204 -226
  45. data/lib/json-schema/validator.rb +173 -156
  46. data/lib/json-schema/validators/draft1.rb +21 -23
  47. data/lib/json-schema/validators/draft2.rb +22 -24
  48. data/lib/json-schema/validators/draft3.rb +26 -28
  49. data/lib/json-schema/validators/draft4.rb +34 -36
  50. data/lib/json-schema/validators/draft6.rb +36 -36
  51. data/lib/json-schema/validators/hyper-draft1.rb +2 -3
  52. data/lib/json-schema/validators/hyper-draft2.rb +2 -3
  53. data/lib/json-schema/validators/hyper-draft3.rb +2 -3
  54. data/lib/json-schema/validators/hyper-draft4.rb +2 -3
  55. data/lib/json-schema/validators/hyper-draft6.rb +2 -3
  56. data/lib/json-schema.rb +3 -3
  57. data/resources/draft-06.json +12 -12
  58. metadata +60 -32
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3361b9ea49eb9e208babcec94973eb5efd0d371c2a2cbab16cca9e6555b11b77
4
- data.tar.gz: 82f4c4d50b75db5d379555c76ca2606580c14d74a0ec5088504cfb5f5025e1ed
3
+ metadata.gz: e9686db47d231f89e17854471084e1dfe27b365df2e5be5e04a98ef27d05cbcf
4
+ data.tar.gz: 5f6e77d40b284308ed64d630e292d57797c0c156bdc8ebaafa12acc3ffcfba7f
5
5
  SHA512:
6
- metadata.gz: 5040893a974d35c4e9833076d8db0073215fdc6330535a4ae7c7d3eef3bdfd902e3642ed5bd9729735b65d8821e30db2b563411d4fd6cf0187c6efe2a4179669
7
- data.tar.gz: 9161d768e8829faafefeabf7723c462019831393d4c696ccbc9b7f7be9f5affcc988cf93a2ce1709ea1b6cddd70230fa44815cd4a3e965b7c15ea65b2b0c3de2
6
+ metadata.gz: bdb9e93be56be04160b301dd200684b20495ffd3326d12dd2ca2014eb6f3bfc667f61ba1a3f61bdb5f39cab20a0edbf509a7efd84cb52ac728219b88c1ad4b61
7
+ data.tar.gz: b62696183483862807c53bcc9ccbf831206800dda4e26f03de0da0f12f556e36a6e01083c853100348f7f9f96c13607d1e7600af41436ceb01eb4ca4966b56a3
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.md)
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
@@ -69,7 +80,7 @@ that the `$schema` attribute takes precedence over the `:version` option during
69
80
  parsing and validation.
70
81
 
71
82
  For further information on json schema itself refer to <a
72
- href="http://spacetelescope.github.io/understanding-json-schema/">Understanding
83
+ href="https://json-schema.org/understanding-json-schema">Understanding
73
84
  JSON Schema</a>.
74
85
 
75
86
  Basic Usage
@@ -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 under 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,15 +3,14 @@ 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('/')}"
11
10
  end
12
11
 
13
- def self.validation_error(processor, message, fragments, current_schema, failed_attribute, record_errors)
14
- error = ValidationError.new(message, fragments, failed_attribute, current_schema)
12
+ def self.validation_error(processor, message, fragments, current_schema, failed_attribute, record_errors, properties = [])
13
+ error = ValidationError.new(message, fragments, failed_attribute, current_schema, properties)
15
14
  if record_errors
16
15
  processor.validation_error(error)
17
16
  else
@@ -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
@@ -30,14 +30,12 @@ module JSON
30
30
  schema = current_schema.schema
31
31
 
32
32
  if schema['properties']
33
- extra_properties = extra_properties - schema['properties'].keys
33
+ 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,29 +7,56 @@ 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
+ # Cannot raise if noAdditionalProperties is true, we need to
21
+ # evaluate each sub schema within the allOf, before raising.
22
+ if options[:noAdditionalProperties] == true
23
+ schema.validate(data, fragments, processor, options.merge(record_errors: true))
24
+ else
25
+ schema.validate(data, fragments, processor, options)
26
+ end
27
+ rescue ValidationError => e
21
28
  valid = false
29
+ message = e.message
22
30
  end
23
31
 
24
32
  diff = validation_errors(processor).count - pre_validation_error_count
33
+
25
34
  while diff > 0
26
- diff = diff - 1
35
+ diff -= 1
27
36
  errors["allOf ##{schema_index}"].push(validation_errors(processor).pop)
28
37
  end
29
38
  end
30
39
 
31
- 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"
40
+ # Find any properties that are missing across all subschemas.
41
+ common_missing_properties = {}
42
+ if options[:noAdditionalProperties] == true && !errors.empty?
43
+ all_property_errors = errors.values.flatten.map(&:properties)
44
+ common_missing_properties = (all_property_errors.first || []).to_set
45
+
46
+ all_property_errors[1..].each do |curr_property_errors|
47
+ common_missing_properties &= curr_property_errors.to_set
48
+ end
49
+ end
50
+
51
+ # PropertiesV4Attribute represents errors that would indicate an
52
+ # additional property was detected. If we filter these out, we should
53
+ # be left with errors that are not dependent on any other sub schema.
54
+ non_missing_property_errors = errors.values.flatten.reject do |error|
55
+ error.failed_attribute == JSON::Schema::PropertiesV4Attribute
56
+ end
57
+
58
+ if !valid || !non_missing_property_errors.empty? || !common_missing_properties.empty?
59
+ message ||= "The property '#{build_fragment(fragments)}' of type #{type_of_data(data)} did not match all of the required schemas"
33
60
  validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
34
61
  validation_errors(processor).last.sub_errors = errors
35
62
  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
@@ -27,7 +27,7 @@ module JSON
27
27
  diff = validation_errors(processor).count - pre_validation_error_count
28
28
  valid = false if diff > 0
29
29
  while diff > 0
30
- diff = diff - 1
30
+ diff -= 1
31
31
  errors["anyOf ##{schema_index}"].push(validation_errors(processor).pop)
32
32
  end
33
33
 
@@ -36,7 +36,7 @@ module JSON
36
36
  data = original_data
37
37
  end
38
38
 
39
- if !valid
39
+ unless valid
40
40
  message = "The property '#{build_fragment(fragments)}' of type #{type_of_data(data)} did not match one or more of the required schemas"
41
41
  validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
42
42
  validation_errors(processor).last.sub_errors = errors
@@ -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,7 +7,7 @@ module JSON
7
7
  'divisibleBy'
8
8
  end
9
9
 
10
- def self.validate(current_schema, data, fragments, processor, validator, options = {})
10
+ def self.validate(current_schema, data, fragments, processor, _validator, options = {})
11
11
  return unless data.is_a?(Numeric)
12
12
 
13
13
  factor = current_schema.schema[keyword]
@@ -3,18 +3,18 @@ require 'json-schema/attribute'
3
3
  module JSON
4
4
  class Schema
5
5
  class EnumAttribute < Attribute
6
- def self.validate(current_schema, data, fragments, processor, validator, options = {})
6
+ def self.validate(current_schema, data, fragments, processor, _validator, options = {})
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])
@@ -6,13 +6,13 @@ module JSON
6
6
  class ExtendsAttribute < Attribute
7
7
  def self.validate(current_schema, data, fragments, processor, validator, options = {})
8
8
  schemas = current_schema.schema['extends']
9
- schemas = [schemas] if !schemas.is_a?(Array)
9
+ schemas = [schemas] unless 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
15
- message = "The extended schema '#{uri.to_s}' cannot be found"
15
+ message = "The extended schema '#{uri}' cannot be found"
16
16
  validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
17
17
  else
18
18
  message = "The property '#{build_fragment(fragments)}' was not a valid schema"
@@ -22,15 +22,17 @@ 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 = nil
26
+ schema = nil
26
27
 
27
28
  if s.is_a?(Hash)
28
29
  uri = current_schema.uri
29
30
  if s['$ref']
30
- ref_uri,ref_schema = JSON::Schema::RefAttribute.get_referenced_uri_and_schema(s, current_schema, validator)
31
+ ref_uri, ref_schema = JSON::Schema::RefAttribute.get_referenced_uri_and_schema(s, current_schema, validator)
31
32
  if ref_schema
32
33
  if s.size == 1 # Check if anything else apart from $ref
33
- uri,schema = ref_uri,ref_schema
34
+ uri = ref_uri
35
+ schema = ref_schema
34
36
  else
35
37
  s = s.dup
36
38
  s.delete '$ref'
@@ -38,10 +40,10 @@ module JSON
38
40
  end
39
41
  end
40
42
  end
41
- schema ||= JSON::Schema.new(s,uri,validator)
43
+ schema ||= JSON::Schema.new(s, uri, validator)
42
44
  end
43
45
 
44
- [uri,schema]
46
+ [uri, schema]
45
47
  end
46
48
  end
47
49
  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
@@ -8,13 +8,11 @@ module JSON
8
8
  @validation_proc = validation_proc
9
9
  end
10
10
 
11
- def validate(current_schema, data, fragments, processor, validator, options = {})
12
- begin
13
- @validation_proc.call data
14
- rescue JSON::Schema::CustomFormatError => e
15
- message = "The property '#{self.class.build_fragment(fragments)}' #{e.message}"
16
- self.class.validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
17
- end
11
+ def validate(current_schema, data, fragments, processor, _validator, options = {})
12
+ @validation_proc.call data
13
+ rescue JSON::Schema::CustomFormatError => e
14
+ message = "The property '#{self.class.build_fragment(fragments)}' #{e.message}"
15
+ self.class.validation_error(processor, message, fragments, current_schema, self.class, options[:record_errors])
18
16
  end
19
17
  end
20
18
  end
@@ -5,7 +5,7 @@ module JSON
5
5
  class DateFormat < FormatAttribute
6
6
  REGEXP = /\A\d{4}-\d{2}-\d{2}\z/
7
7
 
8
- def self.validate(current_schema, data, fragments, processor, validator, options = {})
8
+ def self.validate(current_schema, data, fragments, processor, _validator, options = {})
9
9
  if data.is_a?(String)
10
10
  error_message = "The property '#{build_fragment(fragments)}' must be a date in the format of YYYY-MM-DD"
11
11
  if REGEXP.match(data)
@@ -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
@@ -3,19 +3,20 @@ require 'json-schema/attributes/format'
3
3
  module JSON
4
4
  class Schema
5
5
  class DateTimeFormat < FormatAttribute
6
- REGEXP = /\A\d{4}-\d{2}-\d{2}T(\d{2}):(\d{2}):(\d{2})([\.,]\d+)?(Z|[+-](\d{2})(:?\d{2})?)?\z/
6
+ REGEXP = /\A\d{4}-\d{2}-\d{2}T(\d{2}):(\d{2}):(\d{2})([.,]\d+)?(Z|[+-](\d{2})(:?\d{2})?)?\z/
7
7
 
8
- def self.validate(current_schema, data, fragments, processor, validator, options = {})
8
+ def self.validate(current_schema, data, fragments, processor, _validator, options = {})
9
9
  # Timestamp in restricted ISO-8601 YYYY-MM-DDThh:mm:ssZ with optional decimal fraction of the second
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
@@ -3,8 +3,9 @@ require 'json-schema/attributes/format'
3
3
  module JSON
4
4
  class Schema
5
5
  class DateTimeV4Format < FormatAttribute
6
- def self.validate(current_schema, data, fragments, processor, validator, options = {})
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"
@@ -5,16 +5,16 @@ require 'socket'
5
5
  module JSON
6
6
  class Schema
7
7
  class IPFormat < FormatAttribute
8
- def self.validate(current_schema, data, fragments, processor, validator, options = {})
8
+ def self.validate(current_schema, data, fragments, processor, _validator, options = {})
9
9
  return unless data.is_a?(String)
10
10
 
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
- family = ip_version == 6 ? Socket::AF_INET6 : Socket::AF_INET
17
+ family = (ip_version == 6) ? Socket::AF_INET6 : Socket::AF_INET
18
18
  unless ip && ip.family == family
19
19
  error_message = "The property '#{build_fragment(fragments)}' must be a valid IPv#{ip_version} address"
20
20
  validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
@@ -5,7 +5,7 @@ module JSON
5
5
  class TimeFormat < FormatAttribute
6
6
  REGEXP = /\A(\d{2}):(\d{2}):(\d{2})\z/
7
7
 
8
- def self.validate(current_schema, data, fragments, processor, validator, options = {})
8
+ def self.validate(current_schema, data, fragments, processor, _validator, options = {})
9
9
  if data.is_a?(String)
10
10
  error_message = "The property '#{build_fragment(fragments)}' must be a time in the format of hh:mm:ss"
11
11
  if (m = REGEXP.match(data))
@@ -4,8 +4,9 @@ require 'json-schema/errors/uri_error'
4
4
  module JSON
5
5
  class Schema
6
6
  class UriFormat < FormatAttribute
7
- def self.validate(current_schema, data, fragments, processor, validator, options = {})
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
@@ -3,7 +3,7 @@ require 'json-schema/attribute'
3
3
  module JSON
4
4
  class Schema
5
5
  class LimitAttribute < Attribute
6
- def self.validate(current_schema, data, fragments, processor, validator, options = {})
6
+ def self.validate(current_schema, data, fragments, processor, _validator, options = {})
7
7
  schema = current_schema.schema
8
8
  return unless data.is_a?(acceptable_type) && invalid?(schema, value(data))
9
9
 
@@ -28,7 +28,7 @@ module JSON
28
28
  schema[limit_name]
29
29
  end
30
30
 
31
- def self.exclusive?(schema)
31
+ def self.exclusive?(_schema)
32
32
  false
33
33
  end
34
34
 
@@ -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
@@ -3,11 +3,11 @@ require 'json-schema/attribute'
3
3
  module JSON
4
4
  class Schema
5
5
  class MaxDecimalAttribute < Attribute
6
- def self.validate(current_schema, data, fragments, processor, validator, options = {})
6
+ def self.validate(current_schema, data, fragments, processor, _validator, options = {})
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])