Git Product home page Git Product logo

json-schema's Introduction

Ruby JSON Schema Validator

License Test Release RubyGem Version RubyGem Downloads Donated by Iain Beeston

This library is intended to provide Ruby with an interface for validating JSON objects against a JSON schema conforming to JSON Schema Draft 6. Legacy support for JSON Schema Draft 4, JSON Schema Draft 3, JSON Schema Draft 2, and JSON Schema Draft 1 is also included.

Additional Resources

Version 2.0.0 Upgrade Notes

Please be aware that the upgrade to version 2.0.0 will use Draft-04 by default, so schemas that do not declare a validator using the $schema keyword will use Draft-04 now instead of Draft-03. This is the reason for the major version upgrade.

Version 3.0.0 Upgrade Notes

All individual changes are documented in the CHANGELOG.md. The biggest change is that the new version only supports Ruby 2.5 and newer. Take a look into the gemspec file to see the currently supported Ruby version and also .github/workflows/test.yml to see the Ruby versions we test on.

Installation

From rubygems.org:

gem install json-schema

From the git repo:

gem build json-schema.gemspec
gem install json-schema-*.gem

Validation

Three base validation methods exist:

  1. validate: returns a boolean on whether a validation attempt passes
  2. validate!: throws a JSON::Schema::ValidationError with an appropriate message/trace on where the validation failed
  3. fully_validate: builds an array of validation errors return when validation is complete

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.

By default, the validator uses the JSON Schema Draft 4 specification for validation; however, the user is free to specify additional specifications or extend existing ones. Legacy support for Draft 1, Draft 2, and Draft 3 is included by either passing an optional :version parameter to the validate method (set either as :draft1 or draft2), or by declaring the $schema attribute in the schema and referencing the appropriate specification URI. Note that the $schema attribute takes precedence over the :version option during parsing and validation.

For further information on json schema itself refer to Understanding JSON Schema.

Basic Usage

require "json-schema"

schema = {
  "type" => "object",
  "required" => ["a"],
  "properties" => {
    "a" => {"type" => "integer"}
  }
}

#
# validate ruby objects against a ruby schema
#

# => true
JSON::Validator.validate(schema, { "a" => 5 })
# => false
JSON::Validator.validate(schema, {})

#
# validate a json string against a json schema file
#

require "json"
File.write("schema.json", JSON.dump(schema))

# => true
JSON::Validator.validate('schema.json', '{ "a": 5 }')

#
# raise an error when validation fails
#

# => "The property '#/a' of type String did not match the following type: integer"
begin
  JSON::Validator.validate!(schema, { "a" => "taco" })
rescue JSON::Schema::ValidationError => e
  e.message
end

#
# return an array of error messages when validation fails
#

# => ["The property '#/a' of type String did not match the following type: integer in schema 18a1ffbb-4681-5b00-bd15-2c76aee4b28f"]
JSON::Validator.fully_validate(schema, { "a" => "taco" })

Advanced Options

require "json-schema"

schema = {
  "type"=>"object",
  "required" => ["a"],
  "properties" => {
    "a" => {
      "type" => "integer",
      "default" => 42
    },
    "b" => {
      "type" => "object",
      "properties" => {
        "x" => {
          "type" => "integer"
        }
      }
    }
  }
}

#
# with the `:list` option, a list can be validated against a schema that represents the individual objects
#

# => true
JSON::Validator.validate(schema, [{"a" => 1}, {"a" => 2}, {"a" => 3}], :list => true)
# => false
JSON::Validator.validate(schema, [{"a" => 1}, {"a" => 2}, {"a" => 3}])

#
# with the `:errors_as_objects` option, `#fully_validate` returns errors as hashes instead of strings
#

# => [{:schema=>#<Addressable::URI:0x3ffa69cbeed8 URI:18a1ffbb-4681-5b00-bd15-2c76aee4b28f>, :fragment=>"#/a", :message=>"The property '#/a' of type String did not match the following type: integer in schema 18a1ffbb-4681-5b00-bd15-2c76aee4b28f", :failed_attribute=>"TypeV4"}]
JSON::Validator.fully_validate(schema, { "a" => "taco" }, :errors_as_objects => true)

#
# with the `:strict` option, all properties are considered to have `"required": true` and all objects `"additionalProperties": false`
#

# => true
JSON::Validator.validate(schema, { "a" => 1, "b" => { "x" => 2 } }, :strict => true)
# => false
JSON::Validator.validate(schema, { "a" => 1, "b" => { "x" => 2 }, "c" => 3 }, :strict => true)
# => false
JSON::Validator.validate(schema, { "a" => 1 }, :strict => true)

#
# with the `:fragment` option, only a fragment of the schema is used for validation
#

# => true
JSON::Validator.validate(schema, { "x" => 1 }, :fragment => "#/properties/b")
# => false
JSON::Validator.validate(schema, { "x" => 1 })

#
# with the `:validate_schema` option, the schema is validated (against the json schema spec) before the json is validated (against the specified schema)
#

# => true
JSON::Validator.validate(schema, { "a" => 1 }, :validate_schema => true)
# => false
JSON::Validator.validate({ "required" => true }, { "a" => 1 }, :validate_schema => true)

#
# with the `:insert_defaults` option, any undefined values in the json that have a default in the schema are replaced with the default before validation
#

# => true
JSON::Validator.validate(schema, {}, :insert_defaults => true)
# => false
JSON::Validator.validate(schema, {})

#
# with the `:version` option, schemas conforming to older drafts of the json schema spec can be used
#

v2_schema = {
  "type" => "object",
  "properties" => {
    "a" => {
      "type" => "integer"
    }
  }
}

# => false
JSON::Validator.validate(v2_schema, {}, :version => :draft2)
# => true
JSON::Validator.validate(v2_schema, {})

#
# with the `:parse_data` option set to false, the json must be a parsed ruby object (not a json text, a uri or a file path)
#

# => true
JSON::Validator.validate(schema, { "a" => 1 }, :parse_data => false)
# => false
JSON::Validator.validate(schema, '{ "a": 1 }', :parse_data => false)

#
# with the `:parse_integer` option set to false, the integer value given as string will not be parsed.
#

# => true
JSON::Validator.validate({type: "integer"}, "23")
# => false
JSON::Validator.validate({type: "integer"}, "23", parse_integer: false)
# => true
JSON::Validator.validate({type: "string"}, "123", parse_integer: false)
# => false
JSON::Validator.validate({type: "string"}, "123")

#
# with the `:json` option, the json must be an unparsed json text (not a hash, a uri or a file path)
#

# => true
JSON::Validator.validate(schema, '{ "a": 1 }', :json => true)
# => "no implicit conversion of Hash into String"
begin
  JSON::Validator.validate(schema, { "a" => 1 }, :json => true)
rescue TypeError => e
  e.message
end

#
# with the `:uri` option, the json must be a uri or file path (not a hash or a json text)
#

File.write("data.json", '{ "a": 1 }')

# => true
JSON::Validator.validate(schema, "data.json", :uri => true)
# => "Can't convert Hash into String."
begin
  JSON::Validator.validate(schema, { "a"  => 1 }, :uri => true)
rescue TypeError => e
  e.message
end

#
# with the `:clear_cache` option set to true, the internal cache of schemas is
# cleared after validation (otherwise schemas are cached for efficiency)
#

File.write("schema.json", v2_schema.to_json)

# => true
JSON::Validator.validate("schema.json", {})

File.write("schema.json", schema.to_json)

# => true
JSON::Validator.validate("schema.json", {}, :clear_cache => true)

# => false
JSON::Validator.validate("schema.json", {})

Extending Schemas

For this example, we are going to extend the JSON Schema Draft 3 specification by adding a 'bitwise-and' property for validation.

require "json-schema"

class BitwiseAndAttribute < JSON::Schema::Attribute
  def self.validate(current_schema, data, fragments, processor, validator, options = {})
    if data.is_a?(Integer) && data & current_schema.schema['bitwise-and'].to_i == 0
      message = "The property '#{build_fragment(fragments)}' did not evaluate  to true when bitwise-AND'd with  #{current_schema.schema['bitwise-or']}"
      validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
    end
  end
end

class ExtendedSchema < JSON::Schema::Draft3
  def initialize
    super
    @attributes["bitwise-and"] = BitwiseAndAttribute
    @uri = JSON::Util::URI.parse("http://test.com/test.json")
    @names = ["http://test.com/test.json"]
  end

  JSON::Validator.register_validator(self.new)
end

schema = {
  "$schema" => "http://test.com/test.json",
  "properties" => {
    "a" => {
      "bitwise-and" => 1
    },
    "b" => {
      "type" => "string"
    }
  }
}

data = {
  "a" => 0
}

data = {"a" => 1, "b" => "taco"}
JSON::Validator.validate(schema,data) # => true
data = {"a" => 1, "b" => 5}
JSON::Validator.validate(schema,data) # => false
data = {"a" => 0, "b" => "taco"}
JSON::Validator.validate(schema,data) # => false

Custom format validation

The JSON schema standard allows custom formats in schema definitions which should be ignored by validators that do not support them. JSON::Schema allows registering procs as custom format validators which receive the value to be checked as parameter and must raise a JSON::Schema::CustomFormatError to indicate a format violation. The error message will be prepended by the property name, e.g. The property '#a'

require "json-schema"

format_proc = -> value {
  raise JSON::Schema::CustomFormatError.new("must be 42") unless value == "42"
}

# register the proc for format 'the-answer' for draft4 schema
JSON::Validator.register_format_validator("the-answer", format_proc, ["draft4"])

# omitting the version parameter uses ["draft1", "draft2", "draft3", "draft4"] as default
JSON::Validator.register_format_validator("the-answer", format_proc)

# deregistering the custom validator
# (also ["draft1", "draft2", "draft3", "draft4"] as default version)
JSON::Validator.deregister_format_validator('the-answer', ["draft4"])

# shortcut to restore the default formats for validators (same default as before)
JSON::Validator.restore_default_formats(["draft4"])

# with the validator registered as above, the following results in
# ["The property '#a' must be 42"] as returned errors
schema = {
  "$schema" => "http://json-schema.org/draft-04/schema#",
  "properties" => {
    "a" => {
      "type" => "string",
      "format" => "the-answer",
    }
  }
}
errors = JSON::Validator.fully_validate(schema, {"a" => "23"})

Validating a JSON Schema

To validate that a JSON Schema conforms to the JSON Schema standard, you need to validate your schema against the metaschema for the appropriate JSON Schema Draft. All of the normal validation methods can be used for this. First retrieve the appropriate metaschema from the internal cache (using JSON::Validator.validator_for_name() or JSON::Validator.validator_for_uri()) and then simply validate your schema against it.

require "json-schema"

schema = {
  "type" => "object",
  "properties" => {
    "a" => {"type" => "integer"}
  }
}

metaschema = JSON::Validator.validator_for_name("draft4").metaschema
# => true
JSON::Validator.validate(metaschema, schema)

Controlling Remote Schema Reading

In some cases, you may wish to prevent the JSON Schema library from making HTTP calls or reading local files in order to resolve $ref schemas. If you fully control all schemas which should be used by validation, this could be accomplished by registering all referenced schemas with the validator in advance:

schema = JSON::Schema.new(some_schema_definition, Addressable::URI.parse('http://example.com/my-schema'))
JSON::Validator.add_schema(schema)

If more extensive control is necessary, the JSON::Schema::Reader instance used can be configured in a few ways:

# Change the default schema reader used
JSON::Validator.schema_reader = JSON::Schema::Reader.new(:accept_uri => true, :accept_file => false)

# For this validation call, use a reader which only accepts URIs from my-website.com
schema_reader = JSON::Schema::Reader.new(
  :accept_uri => proc { |uri| uri.host == 'my-website.com' }
)
JSON::Validator.validate(some_schema, some_object, :schema_reader => schema_reader)

The JSON::Schema::Reader interface requires only an object which responds to read(string) and returns a JSON::Schema instance. See the API documentation for more information.

JSON Backends

The JSON Schema library currently supports the json and yajl-ruby backend JSON parsers. If either of these libraries are installed, they will be automatically loaded and used to parse any JSON strings supplied by the user.

If more than one of the supported JSON backends are installed, the yajl-ruby parser is used by default. This can be changed by issuing the following before validation:

JSON::Validator.json_backend = :json

Optionally, the JSON Schema library supports using the MultiJSON library for selecting JSON backends. If the MultiJSON library is installed, it will be autoloaded.

Notes

The 'format' attribute is only validated for the following values:

  • date-time
  • date
  • time
  • ip-address (IPv4 address in draft1, draft2 and draft3)
  • ipv4 (IPv4 address in draft4)
  • ipv6
  • uri

All other 'format' attribute values are simply checked to ensure the instance value is of the correct datatype (e.g., an instance value is validated to be an integer or a float in the case of 'utc-millisec').

Additionally, JSON::Validator does not handle any json hyperschema attributes.

Transfer Notice

This plugin was originally authored by Iain Beeston. The maintainer preferred that Vox Pupuli take ownership of the module for future improvement and maintenance. Existing pull requests and issues were transferred, please fork and continue to contribute here.

License

This gem is licensed under the MIT license.

Release information

To make a new release, please do:

  • update the version in VERSION.yml
  • Install gems with bundle install --with release --path .vendor
  • generate the changelog with bundle exec rake changelog
  • Check if the new version matches the closed issues/PRs in the changelog
  • Create a PR with it
  • After it got merged, push a tag. GitHub actions will do the actual release to rubygems and GitHub Packages

json-schema's People

Contributors

a-lavis avatar apsoto avatar bastelfreak avatar bkirz avatar brancz avatar ekohl avatar gabrielg avatar ghoneycutt avatar goodsimon avatar hoxworth avatar iainbeeston avatar ilikepies avatar isage avatar japgolly avatar jlblcc avatar joshk avatar jwarykowski avatar marshall-lee avatar mjc avatar mohanapriya2308 avatar mpalmer avatar myronmarston avatar ndbroadbent avatar olleolleolle avatar pd avatar rst-j avatar sebbacon avatar take avatar vasfed avatar ydah avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

json-schema's Issues

Validator can't find draft-03.json when in a Warbler/JRuby jar

Set-Up

We are deploying a Ruby app with JRuby (1.6.7.2) and Warbler (1.3.6) as an executable jar. Standard JRuby 1.9 compatibility mode.

Problem

I don't believe that the Validator code is looking within the jar for the draft-03.json metaschema files:

gm14312{bbeaty}504: java -Djruby.compat.version=1.9 -jar quantum-lead/quantum-lead.jar process clevelend
Errno::ENOENT: No such file or directory - /Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/gems/json-schema-1.0.10/resources/draft-03.json
             initialize at org/jruby/RubyFile.java:465
                   open at org/jruby/RubyIO.java:1135
                   open at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/gems/json-schema-1.0.10/lib/json-schema/uri/file.rb:27
                   open at file:/var/folders/y0/w6rwlbtx42v8pkf8sfdck27wgfcp7p/T/jruby1681743642137120687extract/jruby-stdlib-1.6.7.2.jar!/META-INF/jruby.home/lib/ruby/1.9/open-uri.rb:33
      initialize_schema at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/gems/json-schema-1.0.10/lib/json-schema/validator.rb:517
             initialize at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/gems/json-schema-1.0.10/lib/json-schema/validator.rb:164
         fully_validate at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/gems/json-schema-1.0.10/lib/json-schema/validator.rb:324
  fully_validate_schema at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/gems/json-schema-1.0.10/lib/json-schema/validator.rb:331
       validate_schema! at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/quantum-lead/lib/contracts.rb:124
       contractual_proc at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/quantum-lead/lib/contracts.rb:54
           add_contract at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/quantum-lead/lib/contracts.rb:28
                 Client at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/quantum-lead/lib/demand/adjustment/client.rb:52
             Adjustment at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/quantum-lead/lib/demand/adjustment/client.rb:10
                 Demand at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/quantum-lead/lib/demand/adjustment/client.rb:9
                 (root) at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/quantum-lead/lib/demand/adjustment/client.rb:8
                require at org/jruby/RubyKernel.java:1042
                require at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/quantum-lead/lib/demand/adjustment/client.rb:36
                 (root) at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/quantum-lead/lib/demand_etl.rb:4
                require at org/jruby/RubyKernel.java:1042
                require at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/quantum-lead/lib/demand_etl.rb:36
                 (root) at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/quantum-lead/lib/quantum_lead.rb:1
                require at org/jruby/RubyKernel.java:1042
                require at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/quantum-lead/lib/quantum_lead.rb:36
                 (root) at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/quantum-lead/bin/process.rb:27
                require at org/jruby/RubyKernel.java:1042
                require at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/quantum-lead/bin/process.rb:36
                 (root) at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/quantum-lead/bin/quantum-lead.rb:5
                   load at org/jruby/RubyKernel.java:1068
                 (root) at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/quantum-lead/bin/quantum-lead.rb:1
                require at org/jruby/RubyKernel.java:1042
                require at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/META-INF/main.rb:36
                 (root) at <script>:3

The core part of the stack trace is the section:

Errno::ENOENT: No such file or directory - /Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/gems/json-schema-1.0.10/resources/draft-03.json
             initialize at org/jruby/RubyFile.java:465
                   open at org/jruby/RubyIO.java:1135
                   open at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/gems/json-schema-1.0.10/lib/json-schema/uri/file.rb:27
                   open at file:/var/folders/y0/w6rwlbtx42v8pkf8sfdck27wgfcp7p/T/jruby1681743642137120687extract/jruby-stdlib-1.6.7.2.jar!/META-INF/jruby.home/lib/ruby/1.9/open-uri.rb:33
      initialize_schema at file:/Users/bbeaty/Developer/quantum-lead/quantum-lead.jar!/gems/json-schema-1.0.10/lib/json-schema/validator.rb:517

because we can see from the last line, the validator.rb file is being referenced from within the jar file, and then when it tries to find the draft-03.json file, it's in the normal filesystem.

It's not going to find the file because we deploy only the jar.

1.0.9 has ruby 1.9.x dependency; breaks patch compatibility

With 1.8 rubies:

undefined method `require_relative' for main:Object
json-schema-1.0.9/lib/json-schema/attributes/extends.rb:1:in `(root)'

Can find limited use of 1.9 require_relative here:

json-schema-1.0.9/lib/json-schema/attributes/extends.rb:require_relative 'ref'
json-schema-1.0.9/lib/json-schema/attributes/additionalproperties.rb:require_relative 'extends'

Where as if you really intend to go ruby 1.9 only then the gemspec should declare it and it shouldn't be introduced as 1.0.x patch release (buy normal community conventions.)

No error when schema not found

When referencing a non existing schema (incorrect path), the validation is not failing, which is misleading:

{
"type": "object",
"properties": {
"game": {
"allOf": [
{"$ref": "wrong/path/to/schema.json"}
]
}
}
}

Returns "valid" when schema is invalid

This doesn't seem right:

schema = { "type" => "object", "properties" => { "test" => "string" } }
data = { "test" => "foo" }
JSON::Validator.validate!(schema, data)
=> true

The example is an invalid schema, obviously. It should be:

schema = { "type" => "object", "properties" => { "test" => { "type" => "string" } } }

I tried several other schemata I know to be invalid, such as:

schema = { "type" => "unknown" }

and got the same result.

Shouldn't the correct behavior be to raise an exception when the schema is invalid, or at least return false? This is the behavior of libXML in the XML space, and is also the behavior of several Python implementations of JSON schema.

I plan to investigate this and submit a fix, but wanted to raise the issue first in case this is actually the desired behavior, and if so, ask why.

SimpleUUID::UUID conflicts with simple_uuid gem

I know you thought you'd solved this for Issue #9, but it turns out that SimpleUUID::UUID is also already taken by another gem: simple_uuid (which is a dependency of the cassandra gem)

Would it be possible for you to change the module from SimpleUUID to say... JSON::Schema ?

How to validate schema only?

Hi i'm hoping the library has a method to validate a schema only. I'm just interested in if a passed jsons schemas syntax is correct.

Use of String#each breaks Ruby 1.9

validate uses String#each, which was removed from Ruby 1.9. So the library doesn't work if you're on 1.9 without the following preamble:

class String
  alias :each :each_line
end

JSON::Validator modifies schema object

schema = { type: "object" }.freeze
JSON::Validator.validate(schema, { })
# RuntimeError: can't modify frozen Hash

I think that this is bad behaviour for JSON::Validator.validate, it should not modify the schema param. Any thoughts?

maxItems is not working

Hi,

There seems to be a problem with the maxItems (I thinks its using the minItems code). If I validate my JSON data using a different validation tool it works fine.

Regards,

Carlskii

Fail on ruby 1.9.3, jruby 1.6.8 --1.9

json-schema 1.0.9 fails to validate on 1.9 rubies with:

NoMethodError: undefined method `each' for "#":String
    ruby/1.9.1/gems/json-schema-1.0.9/lib/json-schema/validator.rb:92:in `validate'
    ruby/1.9.1/gems/json-schema-1.0.9/lib/json-schema/schema.rb:38:in `validate'
    ruby/1.9.1/gems/json-schema-1.0.9/lib/json-schema/attributes/additionalproperties.rb:18:in `block in validate'
    ruby/1.9.1/gems/json-schema-1.0.9/lib/json-schema/attributes/additionalproperties.rb:15:in `each'
    ruby/1.9.1/gems/json-schema-1.0.9/lib/json-schema/attributes/additionalproperties.rb:15:in `validate'
    ruby/1.9.1/gems/json-schema-1.0.9/lib/json-schema/validator.rb:94:in `block in validate'
    ruby/1.9.1/gems/json-schema-1.0.9/lib/json-schema/validator.rb:92:in `each'
    ruby/1.9.1/gems/json-schema-1.0.9/lib/json-schema/validator.rb:92:in `validate'
    ruby/1.9.1/gems/json-schema-1.0.9/lib/json-schema/schema.rb:38:in `validate'
    ruby/1.9.1/gems/json-schema-1.0.9/lib/json-schema/attributes/properties.rb:15:in `block in validate'
    ruby/1.9.1/gems/json-schema-1.0.9/lib/json-schema/attributes/properties.rb:6:in `each'
    ruby/1.9.1/gems/json-schema-1.0.9/lib/json-schema/attributes/properties.rb:6:in `validate'
    ruby/1.9.1/gems/json-schema-1.0.9/lib/json-schema/validator.rb:94:in `block in validate'
    ruby/1.9.1/gems/json-schema-1.0.9/lib/json-schema/validator.rb:92:in `each'
    ruby/1.9.1/gems/json-schema-1.0.9/lib/json-schema/validator.rb:92:in `validate'
    ruby/1.9.1/gems/json-schema-1.0.9/lib/json-schema/schema.rb:38:in `validate'
    ruby/1.9.1/gems/json-schema-1.0.9/lib/json-schema/validator.rb:174:in `validate'
    ruby/1.9.1/gems/json-schema-1.0.9/lib/json-schema/validator.rb:309:in `validate!'

Doesn't work with 1.9 stdlib JSON

MRI 1.9 has the JSON library baked into the standard library. Unfortunately, the way json-schema looks for a backend makes it impossible to use the JSON library in the stdlib...which makes me sad :(.

Your use of Gem::Specification fails when the JSON gem is not installed, even though require "json" works just fine.

Observe an IRB session on 1.9.2 with a clean gemset:

1.9.2p290 :001 > Gem::Specification::find_by_name('json')
Gem::LoadError: Could not find json (>= 0) amongst []
    from /Users/myron/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/dependency.rb:247:in `to_specs'
    from /Users/myron/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/dependency.rb:256:in `to_spec'
    from /Users/myron/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/specification.rb:434:in `find_by_name'
    from (irb):1
    from /Users/myron/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>'
1.9.2p290 :002 > require 'json'
 => true 
1.9.2p290 :003 > JSON
 => JSON 
1.9.2p290 :004 > JSON.dump(:a => 5)
 => "{\"a\":5}" 
1.9.2p290 :004 > 

Provide secure way of testing

Currently there is quite a logic trying to figure out the incoming data. So, if one calls validate() without :json => true, and incoming data is not in valid format, validator tries very much to match the data. And does to e.g. by opening files from local hard drive.

If that is not desired, the only way to prevent such behavior is to call :json => true, which, unfortunately means, that in-memory structures need to be serialized to json first.

So, if I have some object of unknown type (which my happen to be "/etc/passwd" string), and I want to securely test it, currently I need to convert it to json, and json-parse it again in validator.

I'd like to have 'dumb' validate method, which do not have any fallbacks, if object does not match, it does not match, do not fallback. I.e. in https://github.com/hoxworth/json-schema/blob/master/lib/json-schema/validator.rb#L629 just be

elsif data.is_a?(String) && @options[ :literal_strings ] != true

kind of option.

Add in a validation error structure

From @obfuscurity (yes, I'll actually do this instead of ignore it for another month):

How difficult would it be to pass back an AoH with the property
attribute? For example, instead of:

[6] pry(main)>
JSON::Validator.fully_validate('{"name":"User","properties":{"firstname":{"description":"Name","type":"string","minLength":1,"required":true},"lastname":{"description":"Surname","type":"string","minLength":1,"required":false}}}', '{"firstname":""}', :validate_schema => true)
=> ["The property '#/firstname' was not of a minimum string length of 1 in schema 57060c97-bfe0-5cfd-a710-1b7f675d98e7#"]

You get:

=>
[
{
:property => 'firstname',
:failed_attribute => 'minLength',
:message => "The property '#/firstname' was not of a minimum string length of 1 in schema 57060c97-bfe0-5cfd-a710-1b7f675d98e7#"
}
]

It's not a huge deal, but it could be very useful. Assuming the format
is static I can just regex it out. Either way thank you for this
feature. :)

JSON::Validator.fully_validate returns error for valid schema with "not" keyword in it

Here is a schema and test data for validator:

data    = '{ 
                  "id" : 1,
                  "name" : "Zoo",
                  "keywords" : ["Monkey", "Tiger"]
                }'
      schema  =  '{
            "type": "object",
            "properties": {
                "id": {"type": "integer", "minimum": 1},
                "name": {"type": "string"},
                "keywords": {
                    "type": "array",
                    "items": {
                        "type": "string",
                        "not": {"enum": ["", "Tocan"]}
                      },
                    "uniqueItems": true
                }
            }
        }'

JSON::Validator.validate!(schema, data) return true.
JSON::Validator.fully_validate(schema, data) return array of errors related to "not" keyword in the schema.

Fat arrow vs colon

I think the gem only works with json formatted with fat arrows between label and value. Much json is formatted with a colon in stead of a fat arrow. Is there a way to switch in the validator between the 2 or validate both?

Rutger

Validator is not thread safe

In a threaded environment we need to synchronize around all calls to Validator.validate!(). Otherwise we get bogus errors like the one shown below. In this case, the referenced file does indeed contain complexText; as it does when successfully run single threaded.

Why are we using threads?: Threaded application server (rack, sinatra on jruby), and trying to validate json against a schema just after it is produced but before it is returned.

I suspect this is due to use of @@class_vars for state in Validator, but I still don't quite understanding it well enough to know if would be reasonable to remove those for instance variables, that would avoid the issue. How might I best help on this? Can I offer a test case that demonstrates the problem to start with?

JSON::Schema::ValidationError: The referenced schema 'file:///home/david/src/evri/evrinid/content-store/model/schema/common.json#complexText' cannot be found in schema file:///home/david/src/evri/evrinid/content-store/model/schema/content.json#
    /home/david/src/json-schema/lib/json-schema/validator.rb:41:in `validation_error'
    /home/david/src/json-schema/lib/json-schema/attributes/ref.rb:50:in `validate'
    /home/david/src/json-schema/lib/json-schema/validator.rb:70:in `validate'
    org/jruby/RubyHash.java:1170:in `each'
    /home/david/src/json-schema/lib/json-schema/validator.rb:68:in `validate'
    /home/david/src/json-schema/lib/json-schema/schema.rb:38:in `validate'
    /home/david/src/json-schema/lib/json-schema/attributes/properties.rb:15:in `validate'
    org/jruby/RubyHash.java:1170:in `each'
    /home/david/src/json-schema/lib/json-schema/attributes/properties.rb:6:in `validate'
    /home/david/src/json-schema/lib/json-schema/validator.rb:70:in `validate'
    org/jruby/RubyHash.java:1170:in `each'
    /home/david/src/json-schema/lib/json-schema/validator.rb:68:in `validate'
    /home/david/src/json-schema/lib/json-schema/schema.rb:38:in `validate'
    /home/david/src/json-schema/lib/json-schema/attributes/items.rb:10:in `validate'
    org/jruby/RubyArray.java:1612:in `each'
    org/jruby/RubyEnumerable.java:951:in `each_with_index'
    /home/david/src/json-schema/lib/json-schema/attributes/items.rb:7:in `validate'
    /home/david/src/json-schema/lib/json-schema/validator.rb:70:in `validate'
    org/jruby/RubyHash.java:1170:in `each'
    /home/david/src/json-schema/lib/json-schema/validator.rb:68:in `validate'
    /home/david/src/json-schema/lib/json-schema/schema.rb:38:in `validate'
    /home/david/src/json-schema/lib/json-schema/attributes/properties.rb:15:in `validate'
    org/jruby/RubyHash.java:1170:in `each'
    /home/david/src/json-schema/lib/json-schema/attributes/properties.rb:6:in `validate'
    /home/david/src/json-schema/lib/json-schema/validator.rb:70:in `validate'
    org/jruby/RubyHash.java:1170:in `each'
    /home/david/src/json-schema/lib/json-schema/validator.rb:68:in `validate'
    /home/david/src/json-schema/lib/json-schema/schema.rb:38:in `validate'
    /home/david/src/json-schema/lib/json-schema/attributes/ref.rb:47:in `validate'
    /home/david/src/json-schema/lib/json-schema/validator.rb:70:in `validate'
    org/jruby/RubyHash.java:1170:in `each'
    /home/david/src/json-schema/lib/json-schema/validator.rb:68:in `validate'
    /home/david/src/json-schema/lib/json-schema/schema.rb:38:in `validate'
    /home/david/src/json-schema/lib/json-schema/validator.rb:140:in `validate'
    /home/david/src/json-schema/lib/json-schema/validator.rb:258:in `validate!'

Extending a schema doesn't allow overrides

http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.26 where it says "A schema that extends another schema MAY define additional attributes, constrain existing attributes, or add other constraints."

Seems like it should allow me to extend a base schema and change the type of a property, for example:

{
  "name":"Parent",
  "properties":{
    "id":{
      "type":"string",
      "required":true
    }
  }
}

{
  "name":"Child",
  "extends":"Parent",
  "properties":{
    "id":{
      "type":"integer"
    }
  }
}

If I attempt to validate a Child, it complains that the "id" property is not a string.

UUID class conflict

After adding uuid gem into my project, I've run into an issue with json-schema builtin UUID class.
Both uuid gem and json-scheme uri/uuid file declare class with the same name - UUID. Uuid gem being included after json-schema gem overrides initialize method with one without any arguments - https://github.com/assaf/uuid/blob/master/lib/uuid.rb#L249

So running Validator.validate! an ArgumentError occures at https://github.com/hoxworth/json-schema/blob/master/lib/json-schema/uri/uuid.rb#L80

There may be workaround by including uuidtools gem, however I think json-schema gem should use a namespace for UUID class.

Validate against a schema fragment.

I'm new to json-schema so it might not be a relevant issue.
I have one big json file describing a lot of schemas (mostly small ones) with a lot $ref between schemas, and I need to be able to validate data against one of these "inner" schemas. I can't find a way to do this with json-schema.
Does json-schema support this use case, or am I doing it wrong ?

Validation still requires data hash keys to be strings. Contrary to most recent version's stated purpose.

require 'json-schema'
require 'pp'

  • Validation still depends on hash keys as symbols. This is contrary to the most recent version's notes.

"Make hashes indifferent to strings and symbols when using Ruby in the schema or the data"

$ gem list | grep json => json-schema (2.1.3)

'age' is requried to be an integer

schema = {
"type" => "object",
"required" => ["first_name", "last_name", "ssn", "age"],
"properties" => {
"first_name" => { "type" => "string" },
"last_name" => { "type" => "string" },
"ssn" => { "type" => "string" },
"age" => { "type" => "integer" },
"address" => { "type" => "object" }
}
}

  • validation properly enforced when data hash has string keys

data = {'first_name' => 'Joseph', 'last_name' => 'Smith', 'age' => false, 'ssn' => '123456789', }

pp JSON::Validator.fully_validate(schema, data, :errors_as_objects => true, :validate_schema => true)

-> [{:schema=>
#<URI::Generic:0x007fa714a0c590 URL:b3506251-b386-5804-a591-d72a6b3e417d#>,
:fragment=>"#/age",
:message=>
"The property '#/age' of type FalseClass did not match the following type: integer in schema b3506251-b386-5804-a591-d72a6b3e417d#",
:failed_attribute=>"TypeV4"}]

  • validation does not catch invalid type for 'age'

data = {:first_name => 'Joseph', :last_name => 'Smith', :age => false, :ssn => '123456789', }

pp JSON::Validator.fully_validate(schema, data, :errors_as_objects => true, :validate_schema => true)

=> []

json-schema 2.0.1 broke schema validation

The full validation broke with v2.0.1 when it was fine with v2.0.0, for example:

### BEGIN JSON SCHEMA RUBY CODE
 PAGE_SCHEMA = <<-END_SCHEMA
  {
    "type": "object",
    "title": "page",
    "description": "A Resource Index page of results.",
    "additionalProperties": false,
    "properties": {
      "page": { "type": "number", "required": true },
      "pageCount": { "type": "number", "required": true },
      "prevPage": { "type": ["number","null"], "required": true },
      "nextPage": { "type": ["number","null"], "required": true },
      "links": { "type": "object", "required": true },
      "collection": { "type": "array", "required": true }
    }
  }
  END_SCHEMA
### END JSON SCHEMA RUBY CODE

The validation error reads: "JSON::Schema::ValidationError: The property '#/properties/page/required' of type TrueClass did not match the following type: array in schema http://json-schema.org/draft-04/schema#"

This can't be right for a "required" property, surely?

Is there a method available to get a fully resolved schema as a hash?

Is it possible to retrieve the schema that is constructed internally for validation, including extends, $ref'ed schemas, etc as one fully 'resolved' json-schema hash?

I did not have the time to investigate the internals of the gem yet so I thought i'd ask first. I wrote a half-assed implementation myself for my purposes (documentation of the schema) but I figured this might be something that would be useful to others as well.

Thank you.

Previous draft support

For version 1, the JSON::Schema library needs to support JSON Schema Draft 1 and JSON Schema Draft 2.

Can't validate with fragment

  schema = {
    "type" => "object",
    "required" => ["a","b"],
    "properties" => {
      "a" => {"type" => "integer"},
      "b" => {"type" => "string"},
      "c" => {
        "type" => "object",
        "properties" => {
          "z" => {"type" => "integer"}
        }
      }
    }
  }

  data = {
    "z" => 1
  }

  JSON::Validator.validate!(schema, data, :fragment => "#/properties/c")

Code almost from README, throws "Invalid schema encountered when resolving :fragment option (JSON::Schema::SchemaError)"

PS: In fact, there seem to be many problems with my test case, which is just one long schema with several object in it, like in http://stackoverflow.com/a/9083830. I'm not sure, what number of issues should be created (or what number of changes should I do in my code).

For example, having such schema (with "id"s and "$ref"s) in hash, I can't even start using it, receiving "`rescue in merge': both URI are relative (URI::BadURIError)" at the very beginning.

typo in lib/json-schema/validator.rb at line 270

  def json_backend=(backend)
    backend = backend.to_s
    if @@available_json_backend.include?(backend)
      @@json_backend = backend
    else
      raise JSON::Schema::JsonParseError.new("The JSON backend '#{backend}' could not be found.")
    end
  end

SHOULD BE:
@@available_json_backends

json_schema with old multi_json in Rails context

Hi,
I'm using json_schema within a Rails (3.0.10) project which uses some gems (such as oauth2) tied to an old version of multi_json (~> 1.0.0) which use the old "decode" instead of "load". The problem is this line in validator.rb (line 414):

MultiJson.respond_to?(:load) ? MultiJson.load(s) : MultiJson.decode(s)

The problem is that in the Rails context the module responds to load, even though I am using the old version of multi_json. This seems to have to do with autoloading or something. So what happens is a load method in active_support/dependencies.rb is run and it tries to load the JSON file as a Ruby file!

Perhaps we could make the opposite check?

MultiJson.respond_to?(:decode) ? MultiJson.decode(s) : MultiJson.load(s)

Otherwise, the way I got around was by monkey patch JSON::Schema::Validator (monkey patching MultiJson.load didn't work for some reason)

class JSON::Schema::Validator
  def parse
    MultiJson.decode(s)
  end
end

Thanks
Evan

Hypermedia schema

Any thoughts on how you'd want hypermedia schema validation to work? I'm trying to understand how this is supposed to work.

From: http://tools.ietf.org/html/draft-zyp-json-schema-03

For example, if a schema is defined:

{
  "links": [
    {
      "rel": "self"
      "href": "{id}"
    },
    {
      "rel": "up"
      "href": "{upId}"
    },
    {
      "rel": "children"
      "href": "?upId={id}"
    }
  ]
}

And if a collection of instance resource's JSON representation was retrieved:

GET /Resource/

[
  {
    "id": "thing",
    "upId": "parent"
  },
  {
    "id": "thing2",
    "upId": "parent"
  }
]

This would indicate that for the first item in the collection, its own (self) URI would resolve to "/Resource/thing" and the first item's "up" relation SHOULD be resolved to the resource at "/Resource/parent". The "children" collection would be located at "/Resource/?upId=thing".

If I parse that resource with a schema, should the schema be able to add those links automatically? Should the resource have its own links property?

It's possible that this library doesn't do quite what I want because it essentially just returns true or false. I might be looking for something more like JSON schema powered ActiveModel.

allOf and $ref not working?

Hi,

This is my schema:
{
"type": "object",
"properties": {
"game": {
"allOf": [
{"$ref": "../gameSchema.json"}
]
}
}
}

Whatever is in gameSchema.json doesn't seem to be taken in consideration and the validation is not done. I am sure that the path is correct because it fails in case of a syntax error inside gameSchema.json.

I am using v2.1.3.

Unable to Validate v4 Schema File

When I attempt to validate against a draft v4 schema using JSON::Validator.fully_validate_schema(schema_path, version: :draft4) I receive error messages similar to the following:

The property '#/properties/data/required' of type Array did not match the following type: boolean in schema http://json-schema.org/draft-03/schema#"

I see the same issue without specifying the draft version

Seems like the draft v4 schema JSON resource is a copy of the v3 schema file with some whitespace changes.

Validating an actual JSON document using my v4 schema seems to work without issue.

JSON::Validator.default_validator is being set to draft-03 by default

The daft3 validator is being instantiated after the draft4 and they both call JSON::Validator.register_default_validator. See https://github.com/hoxworth/json-schema/blob/master/lib/json-schema.rb#L23.

Test:

2.0.0-p195 :001 > require 'json-schema'
 => true 
2.0.0-p195 :002 > puts JSON::Validator.default_validator
http://json-schema.org/draft-03/schema
 => nil 

A quick fix is to either require the validators separately in the correct order or sort! the array:

Dir[File.join(File.dirname(__FILE__), "json-schema/validators/*.rb")].sort!.each {|file| require file }

I believe this is also related to issue #61, since there's no $schema defined in the example JSON::Validator.register_default_validator is used, .i.e. draft03.

validate_schema does not use value of $schema

require 'json-schema'

schema = {
  '$schema' => 'http://json-schema.org/draft-03/schema#',
  'properties' => {
    'foo' => { 'type' => 'object', 'required' => 'true' }}}

json = '{"foo":{}}'

JSON::Validator.fully_validate(schema, json) #=> []
JSON::Validator.fully_validate(schema, json, validate_schema: true) # => ValidationError

ISO 8601 date-times do not include UTC offset

The validator for date-time only allows for a datetime in UTC, however the ISO 8601 standard allows for a UTC offset to be given.
Example datetime allowed now:

2012-08-20T00:00:00Z

datetime not allowed in json-schema but is allowed by ISO 8601:

2012-08-20T00:00:00+02:00

I see from the json schema you reference that the former is the recommended datetime format, but doesn't that mean the latter should still be allowed?

dependency with string value

schema:

{
    "type":"object",
    "properties":{
        "a":{"type":"integer"},
        "b":{"type":"integer"}
    },
    "dependencies":{
        "a":"b"
    }
}

data:

{"a" => 1, "b" => 1}

then
NoMethodError: undefined method `each' for "b":String

When the dependency value is an array, it works.

"dependencies":{
    "a":["b"]
}

Schema validation should not clear cache

It looks like $ref schemas are not useable when schema validation is enabled. The following schema is valid, but is only useable to validate documents if schema validation is disabled:

{ 
  "type": "object"
  "definitions": {
    "test": {
      "type": "string"
    }
  },
  "properties": {
    "foo": { "$ref": "#/definitions/test" }
  }
}

The problem seems to be that when validated with :validate_schema, the schema is first validated. Then, the cache is cleared, which has a side-effect of removing the schema for #/definitions/test as well has the schemas for schema itself. Then, when you validate a document against it the $ref fails to resolve.

One easy workaround for this (but not necessarily the right fix) would be to turn schema caching on before validating:

JSON::Validator.cache_schemas = true

This causes the cache to be retained between validating the schema and the data, so the $ref URI resolves. But since this is probably the desired behavior whenever doing a schema validation plus a validation against the schema, it's probably better to implicitly set @@cache_schemas = true when schema validation is requested.

Support for string "format" attribute

I'm looking at attributes/format.rb and am a bit puzzled by the implementation. Why do you do your own parsing? Ruby comes with DateTime, IPv4/v6 address, and URI parsers that are known to work well. They are trivial to use and would allow you to handle all currently defined "format" types (with the possible exception of "email") with very little code.

I'm willing to submit a patch for this, but I suspect that this was a conscious choice, not an omission, so I'm more curious as to your reasoning.

Problem with $ref to validate array property

Hey There,

New to JSON-Schema, so totally expect it to be something I'm doing wrong, but if anyone can look at this Gist and explain what about the $ref I'm doing wrong? I've got some more complex data and I'm trying to re-use schemas. I've distilled it down to a simple test case and I can't tell if it's incorrect syntax on my end, or it's the validator.

Given this gist, I expect the sample data to report validation errors.

It works as expected if I take the schema ref and embed it directly, but when I use $ref, no errors?

Any ideas?

License missing from gemspec

Some companies will only use gems with a certain license.
The canonical and easy way to check is via the gemspec,

via e.g.

spec.license = 'MIT'
# or
spec.licenses = ['MIT', 'GPL-2']

Even for projects that already specify a license, including a license in your gemspec is a good practice, since it is easily
discoverable there without having to check the readme or for a license file.

For example, there is a License Finder gem to help companies ensure all gems they use
meet their licensing needs. This tool depends on license information being available in the gemspec. This is an important enough
issue that even Bundler now generates gems with a default 'MIT' license.

If you need help choosing a license (sorry, I haven't checked your readme or looked for a license file),
github has created a license picker tool.

In case you're wondering how I found you and why I made this issue, it's because I'm collecting stats on gems (I was originally
looking for download data) and decided to collect license metadata,too, and make issues for gemspecs not specifying a license as a public service :).

I hope you'll consider specifying a license in your gemspec. If not, please just close the issue and let me know. In either case, I'll follow up. Thanks!

p.s. I've written a blog post about this project

Breaks with multi_json 1.7.9 (works with 1.7.7)

With multi_json 1.7.9, running spec tests I get a backtrace like this:

/Users/kylo/devel/puppetk/.bundle/gems/ruby/1.8/gems/multi_json-1.7.9/lib/multi_json.rb:106:in `load_adapter': Did not recognize your adapter specification. (ArgumentError)
from /Users/kylo/devel/puppetk/.bundle/gems/ruby/1.8/gems/multi_json-1.7.9/lib/multi_json.rb:99:in `load_adapter'
from /Users/kylo/devel/puppetk/.bundle/gems/ruby/1.8/gems/multi_json-1.7.9/lib/multi_json.rb:89:in `use'
from /Users/kylo/devel/puppetk/.bundle/gems/ruby/1.8/gems/multi_json-1.7.9/lib/multi_json.rb:71:in `adapter'
from /Users/kylo/devel/puppetk/.bundle/gems/ruby/1.8/gems/json-schema-2.1.1/lib/json-schema.rb:14

Problems with $ref schema urls in Rails test environment

Here's my situation:

I have a Rails controller that generates various schemas.

In one such schema, I $ref another schema. The $ref url is generated using the typical Rails url helpers.

The problem arises when I try to run some tests that try to validate some data against the schemas. Since it's running in Rails TEST environment, the generated url's have 'www.example.com' as the HOST. When json-schema tries to open the $ref'ed URL, it gets a 404.

{
  "properties": {
    "foo" : { "$ref" : "http://www.example.com/schemas/foo.json" }
  }
}

I've come up with a hack to work around this, but I think the 'right' solution would be if json-schema had a means of providing pluggable URL resolvers for this type of situation.

I'm considering submitting a patch for this, but I'd like to hear anyone's thoughts on this idea or alternative solutions.

Validation is slow

I did some profiling and found a very simple speed improvement. I'll send a pull request.

union types with schemas don't work with :record_errors => true

union types with schemas work by rescuing ValidationError and continuing to try the next type when one doesn't work.

but ValidationError isn't raised when :record_errors is true, so when the second (or later) union type is the valid one, the error gets added on the first (invalid) union type, and not removed when the valid union type is found.

example with a union type of a schema and 'boolean' follows.

:record_errors is false; works fine:

>> JSON::Validator.validate!({'properties' => {'data' => {'type' => [{'type' => 'object'}, 'boolean']}}}, {'data' => false})
=> true

record_errors is true; reports failure encountered validating the first union type:

>> JSON::Validator.fully_validate({'properties' => {'data' => {'type' => [{'type' => 'object'}, 'boolean']}}}, {'data' => false})
=> ["The property '#/data' of type FalseClass did not match one or more of the following types: object in schema 4e2b2f95-fe4c-5581-b5a7-236873957b50#"]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.