pax_global_header 0000666 0000000 0000000 00000000064 13411675645 0014526 g ustar 00root root 0000000 0000000 52 comment=64da0006ebf98cfa2dacab92b895946b3450b72c
ruby-json-schema-2.8.1/ 0000775 0000000 0000000 00000000000 13411675645 0014724 5 ustar 00root root 0000000 0000000 ruby-json-schema-2.8.1/.gitignore 0000664 0000000 0000000 00000000101 13411675645 0016704 0 ustar 00root root 0000000 0000000 /.project
.*.swp
pkg
*.gem
/Gemfile.lock
.bundle
.idea
/coverage
ruby-json-schema-2.8.1/.gitmodules 0000664 0000000 0000000 00000000212 13411675645 0017074 0 ustar 00root root 0000000 0000000 [submodule "test/test-suite"]
path = test/test-suite
branch = master
url = git://github.com/json-schema-org/JSON-Schema-Test-Suite.git
ruby-json-schema-2.8.1/.travis.yml 0000664 0000000 0000000 00000001003 13411675645 0017027 0 ustar 00root root 0000000 0000000 language: "ruby"
rvm:
- "1.9"
- "2.0"
- "2.1"
- "2.2"
- "2.3"
- "2.4"
- "2.5"
- "jruby-1.7"
- "jruby-9.1"
sudo: false
install:
- bundle install --retry=3
matrix:
include:
- rvm: "1.9"
gemfile: "gemfiles/Gemfile.ruby_19.x"
- rvm: "jruby-1.7"
gemfile: "gemfiles/Gemfile.ruby_19.x"
- rvm: "2.5"
gemfile: "gemfiles/Gemfile.multi_json.x"
- rvm: "2.5"
gemfile: "gemfiles/Gemfile.yajl-ruby.x"
- rvm: "2.5"
gemfile: "gemfiles/Gemfile.uuidtools.x"
ruby-json-schema-2.8.1/CHANGELOG.md 0000664 0000000 0000000 00000004772 13411675645 0016547 0 ustar 00root root 0000000 0000000 # Change Log
All notable changes to this project will be documented in this file.
Please keep to the changelog format described on [keepachangelog.com](http://keepachangelog.com).
This project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
## [2.8.1] - 2019-10-14
### Changed
- All limit classes are now stored in their own files in 'json-schema/attributes/limits'
- All attribute classes are now stored in their own files in 'json-schema/attributes'
### Fixed
- Corrected the draft6 schema id to `http://json-schema.org/draft/schema#`
- Rescue URI error when initializing a data string that contains a colon
- Fragments with an odd number of components no longer raise an `undefined method `validate'`
error
## [2.8.0] - 2017-02-07
### Added
- Ruby 2.4 support
### Changed
- Made the `:clear_cache` option for `validate` also clear the URI parse cache
- Moved `JSON::Validator.absolutize_ref` and the ref manipulating code in
`JSON::Schema::RefAttribute` into `JSON::Util::URI`
- Made validation errors refer to json schema types not ruby types
### Deprecated
- `JSON::Validator#validator_for` in favor of `JSON::Validator#validator_for_uri`
- `JSON::Validator.validate2` in favor of `JSON::Validator.validate!`
- `JSON::Schema::Validator#extend_schema_definition` in favour of subclassing
## [2.7.0] - 2016-09-29
### Fixed
- Made sure we really do clear the cache when instructed to
- It's now possible to use reserved words in property names
- Removed support for setting "extends" to a string (it's invalid json-schema - use a "$ref" instead)
- Relaxed 'items' and 'allowedItems' validation to permit arrays to pass even
when they contain fewer elements than the 'items' array. To require full tuples,
use 'minItems'.
### Changed
- Made all `validate*` methods on `JSON::Validator` ultimately call `validate!`
- Updated addressable dependency to 2.4.0
- Attached failed `uri` or `pathname` to read errors for more meaning
## [2.6.2] - 2016-05-13
### Fixed
- Made it possible to include colons in a $ref
### Changed
- Reformatted examples in the readme
## [2.6.1] - 2016-02-26
### Fixed
- Made sure schemas of an unrecognized type raise a SchemaParseError (not Name error)
### Changed
- Readme was converted from textile to markdown
## [2.6.0] - 2016-01-08
### Added
- Added a changelog
### Changed
- Improved performance by caching the parsing and normalization of URIs
- Made validation failures raise a `JSON::Schema::SchemaParseError` and data
loading failures a `JSON::Schema::JsonLoadError`
ruby-json-schema-2.8.1/CONTRIBUTING.md 0000664 0000000 0000000 00000001576 13411675645 0017166 0 ustar 00root root 0000000 0000000 The Ruby JSON Schema library is meant to be a community effort, and as such, there are no strict guidelines for contributing.
All individuals that have a pull request merged will receive collaborator access to the repository. Due to the restrictions on RubyGems authentication, permissions to release a gem must be requested along with the email desired to be associated with the release credentials.
Accepting changes to the JSON Schema library shall be made through the use of pull requests on GitHub. A pull request must receive at least two (2) "+1" comments from current contributors, and include a relevant changelog entry, before being accepted and merged. If a breaking issue and fix exists, please feel free to contact the project maintainer at hoxworth@gmail.com or @hoxworth for faster resolution.
Releases follow semantic versioning and may be made at a maintainer's discretion.
ruby-json-schema-2.8.1/CONTRIBUTORS.md 0000664 0000000 0000000 00000001552 13411675645 0017206 0 ustar 00root root 0000000 0000000 CONTRIBUTORS
------------
* Kenny Hoxworth - @hoxworth
* Jenny Duckett - @jennyd
* Kevin Glowacz - @kjg
* Seb Bacon - @sebbacon
* Jonathan Chrisp - @jonathanchrisp
* James McKinney - @jpmckinney
* Kylo Ginsberg - @kylog
* Alex Soto - @apsoto
* Roger Leite - @rogerleite
* Myron Marston - @myronmarston
* Jesse Stuart - @jvatic
* Brian Hoffman - @lcdhoffman
* Simon Waddington - @goodsimon
* Chris Baynes - @chris-baynes
* David Barri - @japgolly
* Tyler Hunt - @tylerhunt
* @vapir
* Tom May - @tommay
* Chris Johnson - @kindkid
* David Kellum - @dekellum
* Miguel Herranz - @IPGlider
* Nick Recobra - @oruen
* Vasily Fedoseyev - @Vasfed
* Jari Bakken - @jarib
* Kyle Hargraves - @pd
* Jamie Cobbett - @jamiecobbett
* Iain Beeston - @iainbeeston
* Matt Palmer - @mpalmer
* Ben Kirzhner - @benkirzhner
* RST-J - @RST-J
* Christian Treppo - @treppo
* Benjamin Falk - @benfalk
ruby-json-schema-2.8.1/Gemfile 0000664 0000000 0000000 00000000167 13411675645 0016223 0 ustar 00root root 0000000 0000000 source "https://rubygems.org"
gemspec
gem "json", ">= 1.7", :platforms => :mri_19
gem 'simplecov', :require => false
ruby-json-schema-2.8.1/LICENSE.md 0000664 0000000 0000000 00000002065 13411675645 0016333 0 ustar 00root root 0000000 0000000 Copyright (c) 2010-2011, Lookingglass Cyber Solutions
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. ruby-json-schema-2.8.1/README.md 0000664 0000000 0000000 00000034176 13411675645 0016216 0 ustar 00root root 0000000 0000000 [](https://badge.fury.io/rb/json-schema)
[](https://travis-ci.org/ruby-json-schema/json-schema)
[](https://codeclimate.com/github/ruby-json-schema/json-schema)
Ruby JSON Schema Validator
==========================
This library is intended to provide Ruby with an interface for validating JSON
objects against a JSON schema conforming to [JSON Schema Draft
4](http://tools.ietf.org/html/draft-zyp-json-schema-04). Legacy support for
[JSON Schema Draft 3](http://tools.ietf.org/html/draft-zyp-json-schema-03),
[JSON Schema Draft 2](http://tools.ietf.org/html/draft-zyp-json-schema-02), and
[JSON Schema Draft 1](http://tools.ietf.org/html/draft-zyp-json-schema-01) is
also included.
Additional Resources
--------------------
- [Google Groups](https://groups.google.com/forum/#!forum/ruby-json-schema)
- #ruby-json-schema on chat.freenode.net
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.
Installation
------------
From rubygems.org:
```sh
gem install json-schema
```
From the git repo:
```sh
$ gem build json-schema.gemspec
$ gem install json-schema-2.5.2.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](http://tools.ietf.org/html/draft-zyp-json-schema-04) 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
--------------
```ruby
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
-----------------
```ruby
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=>#, :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 condisidered 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 `: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](http://tools.ietf.org/html/draft-zyp-json-schema-03) specification by adding
a 'bitwise-and' property for validation.
```ruby
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']()
```ruby
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.
```ruby
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:
```ruby
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:
```ruby
# 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](http://www.rubydoc.info/github/ruby-json-schema/json-schema/master/JSON/Schema/Reader)
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:
```ruby
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.
ruby-json-schema-2.8.1/Rakefile 0000664 0000000 0000000 00000003064 13411675645 0016374 0 ustar 00root root 0000000 0000000 require 'bundler'
require 'rake'
require 'rake/testtask'
Bundler::GemHelper.install_tasks
desc "Updates the json-schema common test suite to the latest version"
task :update_common_tests do
unless File.read(".git/config").include?('submodule "test/test-suite"')
sh "git submodule init"
end
puts "Updating json-schema common test suite..."
begin
sh "git submodule update --remote --quiet"
rescue StandardError
STDERR.puts "Failed to update common test suite."
end
end
desc "Update meta-schemas to the latest version"
task :update_meta_schemas do
puts "Updating meta-schemas..."
id_mappings = {
'http://json-schema.org/draft/schema#' => 'https://raw.githubusercontent.com/json-schema-org/json-schema-spec/master/schema.json'
}
require 'open-uri'
require 'thwait'
download_threads = Dir['resources/*.json'].map do |path|
schema_id = File.read(path)[/"\$?id"\s*:\s*"(.*?)"/, 1]
schema_uri = id_mappings[schema_id] || schema_id
Thread.new(schema_uri) do |uri|
Thread.current[:uri] = uri
begin
metaschema = URI(uri).read
File.write(path, metaschema)
rescue StandardError
false
end
end
end
ThreadsWait.all_waits(*download_threads) do |t|
if t.value
puts t[:uri]
else
STDERR.puts "Failed to update meta-schema #{t[:uri]}"
end
end
end
Rake::TestTask.new do |t|
t.libs << "."
t.warning = true
t.verbose = true
t.test_files = FileList.new('test/*_test.rb')
end
task update: [:update_common_tests, :update_meta_schemas]
task :default => :test
ruby-json-schema-2.8.1/VERSION.yml 0000664 0000000 0000000 00000000033 13411675645 0016570 0 ustar 00root root 0000000 0000000 major: 2
minor: 8
patch: 1
ruby-json-schema-2.8.1/gemfiles/ 0000775 0000000 0000000 00000000000 13411675645 0016517 5 ustar 00root root 0000000 0000000 ruby-json-schema-2.8.1/gemfiles/Gemfile.multi_json.x 0000664 0000000 0000000 00000000110 13411675645 0022432 0 ustar 00root root 0000000 0000000 source "https://rubygems.org"
gemspec :path => "../"
gem "multi_json"
ruby-json-schema-2.8.1/gemfiles/Gemfile.ruby_19.x 0000664 0000000 0000000 00000000174 13411675645 0021553 0 ustar 00root root 0000000 0000000 source "https://rubygems.org"
gemspec :path => "../"
gem "json", "~> 1.0"
gem "addressable", "< 2.5"
gem "webmock", "< 3"
ruby-json-schema-2.8.1/gemfiles/Gemfile.uuidtools.x 0000664 0000000 0000000 00000000107 13411675645 0022304 0 ustar 00root root 0000000 0000000 source "https://rubygems.org"
gemspec :path => "../"
gem "uuidtools"
ruby-json-schema-2.8.1/gemfiles/Gemfile.yajl-ruby.x 0000664 0000000 0000000 00000000107 13411675645 0022173 0 ustar 00root root 0000000 0000000 source "https://rubygems.org"
gemspec :path => "../"
gem "yajl-ruby"
ruby-json-schema-2.8.1/json-schema.gemspec 0000664 0000000 0000000 00000001576 13411675645 0020511 0 ustar 00root root 0000000 0000000 require 'yaml'
version_yaml = YAML.load(File.open('VERSION.yml').read)
version = "#{version_yaml['major']}.#{version_yaml['minor']}.#{version_yaml['patch']}"
gem_name = "json-schema"
Gem::Specification.new do |s|
s.name = gem_name
s.version = version
s.authors = ["Kenny Hoxworth"]
s.email = "hoxworth@gmail.com"
s.homepage = "http://github.com/ruby-json-schema/json-schema/tree/master"
s.summary = "Ruby JSON Schema Validator"
s.files = Dir[ "lib/**/*", "resources/*.json" ]
s.require_path = "lib"
s.extra_rdoc_files = ["README.md","LICENSE.md"]
s.required_ruby_version = ">= 1.9"
s.license = "MIT"
s.required_rubygems_version = ">= 1.8"
s.add_development_dependency "rake"
s.add_development_dependency "minitest", '~> 5.0'
s.add_development_dependency "webmock"
s.add_development_dependency "bundler"
s.add_runtime_dependency "addressable", '>= 2.4'
end
ruby-json-schema-2.8.1/lib/ 0000775 0000000 0000000 00000000000 13411675645 0015472 5 ustar 00root root 0000000 0000000 ruby-json-schema-2.8.1/lib/json-schema.rb 0000664 0000000 0000000 00000001356 13411675645 0020233 0 ustar 00root root 0000000 0000000 require 'rubygems'
if Gem::Specification::find_all_by_name('multi_json').any?
require 'multi_json'
# Force MultiJson to load an engine before we define the JSON constant here; otherwise,
# it looks for things that are under the JSON namespace that aren't there (since we have defined it here)
MultiJson.respond_to?(:adapter) ? MultiJson.adapter : MultiJson.engine
end
require 'json-schema/util/array_set'
require 'json-schema/util/uri'
require 'json-schema/schema'
require 'json-schema/schema/reader'
require 'json-schema/validator'
Dir[File.join(File.dirname(__FILE__), "json-schema/attributes/**/*.rb")].each {|file| require file }
Dir[File.join(File.dirname(__FILE__), "json-schema/validators/*.rb")].sort!.each {|file| require file }
ruby-json-schema-2.8.1/lib/json-schema/ 0000775 0000000 0000000 00000000000 13411675645 0017701 5 ustar 00root root 0000000 0000000 ruby-json-schema-2.8.1/lib/json-schema/attribute.rb 0000664 0000000 0000000 00000002765 13411675645 0022243 0 ustar 00root root 0000000 0000000 require 'json-schema/errors/validation_error'
module JSON
class Schema
class Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
end
def self.build_fragment(fragments)
"#/#{fragments.join('/')}"
end
def self.validation_error(processor, message, fragments, current_schema, failed_attribute, record_errors)
error = ValidationError.new(message, fragments, failed_attribute, current_schema)
if record_errors
processor.validation_error(error)
else
raise error
end
end
def self.validation_errors(validator)
validator.validation_errors
end
TYPE_CLASS_MAPPINGS = {
"string" => String,
"number" => Numeric,
"integer" => Integer,
"boolean" => [TrueClass, FalseClass],
"object" => Hash,
"array" => Array,
"null" => NilClass,
"any" => Object
}
def self.data_valid_for_type?(data, type)
valid_classes = TYPE_CLASS_MAPPINGS.fetch(type) { return true }
Array(valid_classes).any? { |c| data.is_a?(c) }
end
# Lookup Schema type of given class instance
def self.type_of_data(data)
type, _ = TYPE_CLASS_MAPPINGS.map { |k,v| [k,v] }.sort_by { |(_, v)|
-Array(v).map { |klass| klass.ancestors.size }.max
}.find { |(_, v)|
Array(v).any? { |klass| data.kind_of?(klass) }
}
type
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/ 0000775 0000000 0000000 00000000000 13411675645 0022067 5 ustar 00root root 0000000 0000000 ruby-json-schema-2.8.1/lib/json-schema/attributes/additionalitems.rb 0000664 0000000 0000000 00000002063 13411675645 0025567 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
module JSON
class Schema
class AdditionalItemsAttribute < Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
return unless data.is_a?(Array)
schema = current_schema.schema
return unless schema['items'].is_a?(Array)
case schema['additionalItems']
when false
if schema['items'].length < data.length
message = "The property '#{build_fragment(fragments)}' contains additional array elements outside of the schema when none are allowed"
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
end
when Hash
additional_items_schema = JSON::Schema.new(schema['additionalItems'], current_schema.uri, validator)
data.each_with_index do |item, i|
next if i < schema['items'].length
additional_items_schema.validate(item, fragments + [i.to_s], processor, options)
end
end
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/additionalproperties.rb 0000664 0000000 0000000 00000004451 13411675645 0026645 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
require 'json-schema/attributes/extends'
module JSON
class Schema
class AdditionalPropertiesAttribute < Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
schema = current_schema.schema
return unless data.is_a?(Hash) && (schema['type'].nil? || schema['type'] == 'object')
extra_properties = remove_valid_properties(data.keys, current_schema, validator)
addprop = schema['additionalProperties']
if addprop.is_a?(Hash)
matching_properties = extra_properties # & addprop.keys
matching_properties.each do |key|
additional_property_schema = JSON::Schema.new(addprop, current_schema.uri, validator)
additional_property_schema.validate(data[key], fragments + [key], processor, options)
end
extra_properties -= matching_properties
end
if extra_properties.any? && (addprop == false || (addprop.is_a?(Hash) && !addprop.empty?))
message = "The property '#{build_fragment(fragments)}' contains additional properties #{extra_properties.inspect} outside of the schema when none are allowed"
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
end
end
def self.remove_valid_properties(extra_properties, current_schema, validator)
schema = current_schema.schema
if schema['properties']
extra_properties = extra_properties - schema['properties'].keys
end
if schema['patternProperties']
schema['patternProperties'].each_key do |key|
regexp = Regexp.new(key)
extra_properties.reject! { |prop| regexp.match(prop) }
end
end
if extended_schemas = schema['extends']
extended_schemas = [extended_schemas] unless extended_schemas.is_a?(Array)
extended_schemas.each do |schema_value|
_, extended_schema = JSON::Schema::ExtendsAttribute.get_extended_uri_and_schema(schema_value, current_schema, validator)
if extended_schema
extra_properties = remove_valid_properties(extra_properties, extended_schema, validator)
end
end
end
extra_properties
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/allof.rb 0000664 0000000 0000000 00000003117 13411675645 0023513 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
module JSON
class Schema
class AllOfAttribute < Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
# Create an hash to hold errors that are generated during validation
errors = Hash.new { |hsh, k| hsh[k] = [] }
valid = true
current_schema.schema['allOf'].each_with_index do |element, schema_index|
schema = JSON::Schema.new(element,current_schema.uri,validator)
# We're going to add a little cruft here to try and maintain any validation errors that occur in the allOf
# We'll handle this by keeping an error count before and after validation, extracting those errors and pushing them onto an error array
pre_validation_error_count = validation_errors(processor).count
begin
schema.validate(data,fragments,processor,options)
rescue ValidationError
valid = false
end
diff = validation_errors(processor).count - pre_validation_error_count
while diff > 0
diff = diff - 1
errors["allOf ##{schema_index}"].push(validation_errors(processor).pop)
end
end
if !valid || !errors.empty?
message = "The property '#{build_fragment(fragments)}' of type #{type_of_data(data)} did not match all of the required schemas"
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
validation_errors(processor).last.sub_errors = errors
end
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/anyof.rb 0000664 0000000 0000000 00000003477 13411675645 0023543 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
module JSON
class Schema
class AnyOfAttribute < Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
# Create a hash to hold errors that are generated during validation
errors = Hash.new { |hsh, k| hsh[k] = [] }
valid = false
original_data = data.is_a?(Hash) ? data.clone : data
current_schema.schema['anyOf'].each_with_index do |element, schema_index|
schema = JSON::Schema.new(element,current_schema.uri,validator)
# We're going to add a little cruft here to try and maintain any validation errors that occur in the anyOf
# We'll handle this by keeping an error count before and after validation, extracting those errors and pushing them onto a union error
pre_validation_error_count = validation_errors(processor).count
begin
schema.validate(data,fragments,processor,options)
valid = true
rescue ValidationError
# We don't care that these schemas don't validate - we only care that one validated
end
diff = validation_errors(processor).count - pre_validation_error_count
valid = false if diff > 0
while diff > 0
diff = diff - 1
errors["anyOf ##{schema_index}"].push(validation_errors(processor).pop)
end
break if valid
data = original_data
end
if !valid
message = "The property '#{build_fragment(fragments)}' of type #{type_of_data(data)} did not match one or more of the required schemas"
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
validation_errors(processor).last.sub_errors = errors
end
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/dependencies.rb 0000664 0000000 0000000 00000002770 13411675645 0025050 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
module JSON
class Schema
class DependenciesAttribute < Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
return unless data.is_a?(Hash)
current_schema.schema['dependencies'].each do |property, dependency_value|
next unless data.has_key?(property.to_s)
next unless accept_value?(dependency_value)
case dependency_value
when String
validate_dependency(current_schema, data, property, dependency_value, fragments, processor, self, options)
when Array
dependency_value.each do |value|
validate_dependency(current_schema, data, property, value, fragments, processor, self, options)
end
else
schema = JSON::Schema.new(dependency_value, current_schema.uri, validator)
schema.validate(data, fragments, processor, options)
end
end
end
def self.validate_dependency(schema, data, property, value, fragments, processor, attribute, options)
return if data.key?(value.to_s)
message = "The property '#{build_fragment(fragments)}' has a property '#{property}' that depends on a missing property '#{value}'"
validation_error(processor, message, fragments, schema, attribute, options[:record_errors])
end
def self.accept_value?(value)
value.is_a?(String) || value.is_a?(Array) || value.is_a?(Hash)
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/dependencies_v4.rb 0000664 0000000 0000000 00000000364 13411675645 0025456 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/dependencies'
module JSON
class Schema
class DependenciesV4Attribute < DependenciesAttribute
def self.accept_value?(value)
value.is_a?(Array) || value.is_a?(Hash)
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/disallow.rb 0000664 0000000 0000000 00000000606 13411675645 0024234 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
module JSON
class Schema
class DisallowAttribute < Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
return unless type = validator.attributes['type']
type.validate(current_schema, data, fragments, processor, validator, options.merge(:disallow => true))
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/divisibleby.rb 0000664 0000000 0000000 00000001261 13411675645 0024721 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
module JSON
class Schema
class DivisibleByAttribute < Attribute
def self.keyword
'divisibleBy'
end
def self.validate(current_schema, data, fragments, processor, validator, options = {})
return unless data.is_a?(Numeric)
factor = current_schema.schema[keyword]
if factor == 0 || factor == 0.0 || (BigDecimal(data.to_s) % BigDecimal(factor.to_s)).to_f != 0
message = "The property '#{build_fragment(fragments)}' was not divisible by #{factor}"
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
end
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/enum.rb 0000664 0000000 0000000 00000001366 13411675645 0023366 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
module JSON
class Schema
class EnumAttribute < Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
enum = current_schema.schema['enum']
return if enum.include?(data)
values = enum.map { |val|
case val
when nil then 'null'
when Array then 'array'
when Hash then 'object'
else val.to_s
end
}.join(', ')
message = "The property '#{build_fragment(fragments)}' value #{data.inspect} did not match one of the following values: #{values}"
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/extends.rb 0000664 0000000 0000000 00000003265 13411675645 0024074 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
require 'json-schema/attributes/ref'
module JSON
class Schema
class ExtendsAttribute < Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
schemas = current_schema.schema['extends']
schemas = [schemas] if !schemas.is_a?(Array)
schemas.each do |s|
uri,schema = get_extended_uri_and_schema(s, current_schema, validator)
if schema
schema.validate(data, fragments, processor, options)
elsif uri
message = "The extended schema '#{uri.to_s}' cannot be found"
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
else
message = "The property '#{build_fragment(fragments)}' was not a valid schema"
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
end
end
end
def self.get_extended_uri_and_schema(s, current_schema, validator)
uri,schema = nil,nil
if s.is_a?(Hash)
uri = current_schema.uri
if s['$ref']
ref_uri,ref_schema = JSON::Schema::RefAttribute.get_referenced_uri_and_schema(s, current_schema, validator)
if ref_schema
if s.size == 1 # Check if anything else apart from $ref
uri,schema = ref_uri,ref_schema
else
s = s.dup
s.delete '$ref'
s = ref_schema.schema.merge(s)
end
end
end
schema ||= JSON::Schema.new(s,uri,validator)
end
[uri,schema]
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/format.rb 0000664 0000000 0000000 00000001000 13411675645 0023673 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
module JSON
class Schema
class FormatAttribute < Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
return unless data_valid_for_type?(data, current_schema.schema['type'])
format = current_schema.schema['format'].to_s
validator = validator.formats[format]
validator.validate(current_schema, data, fragments, processor, validator, options) unless validator.nil?
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/formats/ 0000775 0000000 0000000 00000000000 13411675645 0023542 5 ustar 00root root 0000000 0000000 ruby-json-schema-2.8.1/lib/json-schema/attributes/formats/custom.rb 0000664 0000000 0000000 00000001257 13411675645 0025406 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/format'
require 'json-schema/errors/custom_format_error'
module JSON
class Schema
class CustomFormat < FormatAttribute
def initialize(validation_proc)
@validation_proc = validation_proc
end
def validate(current_schema, data, fragments, processor, validator, options = {})
begin
@validation_proc.call data
rescue JSON::Schema::CustomFormatError => e
message = "The property '#{self.class.build_fragment(fragments)}' #{e.message}"
self.class.validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
end
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/formats/date.rb 0000664 0000000 0000000 00000001552 13411675645 0025007 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/format'
module JSON
class Schema
class DateFormat < FormatAttribute
REGEXP = /\A\d{4}-\d{2}-\d{2}\z/
def self.validate(current_schema, data, fragments, processor, validator, options = {})
if data.is_a?(String)
error_message = "The property '#{build_fragment(fragments)}' must be a date in the format of YYYY-MM-DD"
if REGEXP.match(data)
begin
Date.parse(data)
rescue ArgumentError => e
raise e unless e.message == 'invalid date'
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
end
else
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
end
end
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/formats/date_time.rb 0000664 0000000 0000000 00000003306 13411675645 0026024 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/format'
module JSON
class Schema
class DateTimeFormat < FormatAttribute
REGEXP = /\A\d{4}-\d{2}-\d{2}T(\d{2}):(\d{2}):(\d{2})([\.,]\d+)?(Z|[+-](\d{2})(:?\d{2})?)?\z/
def self.validate(current_schema, data, fragments, processor, validator, options = {})
# Timestamp in restricted ISO-8601 YYYY-MM-DDThh:mm:ssZ with optional decimal fraction of the second
if data.is_a?(String)
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"
if (m = REGEXP.match(data))
parts = data.split("T")
begin
Date.parse(parts[0])
rescue ArgumentError => e
raise e unless e.message == 'invalid date'
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
return
end
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if m.length < 4
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if m[1].to_i > 23
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if m[2].to_i > 59
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if m[3].to_i > 59
else
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
end
end
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/formats/date_time_v4.rb 0000664 0000000 0000000 00000001051 13411675645 0026430 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/format'
module JSON
class Schema
class DateTimeV4Format < FormatAttribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
return unless data.is_a?(String)
DateTime.rfc3339(data)
rescue ArgumentError
error_message = "The property '#{build_fragment(fragments)}' must be a valid RFC3339 date/time string"
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/formats/ip.rb 0000664 0000000 0000000 00000002021 13411675645 0024472 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/format'
require 'ipaddr'
require 'socket'
module JSON
class Schema
class IPFormat < FormatAttribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
return unless data.is_a?(String)
begin
ip = IPAddr.new(data)
rescue ArgumentError => e
raise e unless e.message == 'invalid address'
end
family = ip_version == 6 ? Socket::AF_INET6 : Socket::AF_INET
unless ip && ip.family == family
error_message = "The property '#{build_fragment(fragments)}' must be a valid IPv#{ip_version} address"
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
end
end
def self.ip_version
raise NotImplementedError
end
end
class IP4Format < IPFormat
def self.ip_version
4
end
end
class IP6Format < IPFormat
def self.ip_version
6
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/formats/time.rb 0000664 0000000 0000000 00000002013 13411675645 0025021 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/format'
module JSON
class Schema
class TimeFormat < FormatAttribute
REGEXP = /\A(\d{2}):(\d{2}):(\d{2})\z/
def self.validate(current_schema, data, fragments, processor, validator, options = {})
if data.is_a?(String)
error_message = "The property '#{build_fragment(fragments)}' must be a time in the format of hh:mm:ss"
if (m = REGEXP.match(data))
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if m[1].to_i > 23
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if m[2].to_i > 59
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors]) and return if m[3].to_i > 59
else
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
end
end
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/formats/uri.rb 0000664 0000000 0000000 00000001142 13411675645 0024664 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/format'
require 'json-schema/errors/uri_error'
module JSON
class Schema
class UriFormat < FormatAttribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
return unless data.is_a?(String)
error_message = "The property '#{build_fragment(fragments)}' must be a valid URI"
begin
JSON::Util::URI.parse(data)
rescue JSON::Schema::UriError
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
end
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/items.rb 0000664 0000000 0000000 00000001520 13411675645 0023533 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
module JSON
class Schema
class ItemsAttribute < Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
return unless data.is_a?(Array)
items = current_schema.schema['items']
case items
when Hash
schema = JSON::Schema.new(items, current_schema.uri, validator)
data.each_with_index do |item, i|
schema.validate(item, fragments + [i.to_s], processor, options)
end
when Array
items.each_with_index do |item_schema, i|
break if i >= data.length
schema = JSON::Schema.new(item_schema, current_schema.uri, validator)
schema.validate(data[i], fragments + [i.to_s], processor, options)
end
end
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/limit.rb 0000664 0000000 0000000 00000002425 13411675645 0023535 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
module JSON
class Schema
class LimitAttribute < Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
schema = current_schema.schema
return unless data.is_a?(acceptable_type) && invalid?(schema, value(data))
property = build_fragment(fragments)
description = error_message(schema)
message = format("The property '%s' %s", property, description)
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
end
def self.invalid?(schema, data)
exclusive = exclusive?(schema)
limit = limit(schema)
if limit_name.start_with?('max')
exclusive ? data >= limit : data > limit
else
exclusive ? data <= limit : data < limit
end
end
def self.limit(schema)
schema[limit_name]
end
def self.exclusive?(schema)
false
end
def self.value(data)
data
end
def self.acceptable_type
raise NotImplementedError
end
def self.error_message(schema)
raise NotImplementedError
end
def self.limit_name
raise NotImplementedError
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/limits/ 0000775 0000000 0000000 00000000000 13411675645 0023370 5 ustar 00root root 0000000 0000000 ruby-json-schema-2.8.1/lib/json-schema/attributes/limits/items.rb 0000664 0000000 0000000 00000000365 13411675645 0025042 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/limit'
module JSON
class Schema
class ItemsLimitAttribute < LimitAttribute
def self.acceptable_type
Array
end
def self.value(data)
data.length
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/limits/length.rb 0000664 0000000 0000000 00000000367 13411675645 0025204 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/limit'
module JSON
class Schema
class LengthLimitAttribute < LimitAttribute
def self.acceptable_type
String
end
def self.value(data)
data.length
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/limits/max_items.rb 0000664 0000000 0000000 00000000460 13411675645 0025703 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/limits/items'
module JSON
class Schema
class MaxItemsAttribute < ItemsLimitAttribute
def self.limit_name
'maxItems'
end
def self.error_message(schema)
"had more items than the allowed #{limit(schema)}"
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/limits/max_length.rb 0000664 0000000 0000000 00000000472 13411675645 0026046 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/limits/length'
module JSON
class Schema
class MaxLengthAttribute < LengthLimitAttribute
def self.limit_name
'maxLength'
end
def self.error_message(schema)
"was not of a maximum string length of #{limit(schema)}"
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/limits/max_properties.rb 0000664 0000000 0000000 00000000511 13411675645 0026753 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/limits/properties'
module JSON
class Schema
class MaxPropertiesAttribute < PropertiesLimitAttribute
def self.limit_name
'maxProperties'
end
def self.error_message(schema)
"had more properties than the allowed #{limit(schema)}"
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/limits/maximum.rb 0000664 0000000 0000000 00000000427 13411675645 0025375 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/limits/numeric'
module JSON
class Schema
class MaximumAttribute < NumericLimitAttribute
def self.limit_name
'maximum'
end
def self.exclusive?(schema)
schema['exclusiveMaximum']
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/limits/maximum_inclusive.rb 0000664 0000000 0000000 00000000354 13411675645 0027455 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/limits/maximum'
module JSON
class Schema
class MaximumInclusiveAttribute < MaximumAttribute
def self.exclusive?(schema)
schema['maximumCanEqual'] == false
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/limits/min_items.rb 0000664 0000000 0000000 00000000472 13411675645 0025704 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/limits/items'
module JSON
class Schema
class MinItemsAttribute < ItemsLimitAttribute
def self.limit_name
'minItems'
end
def self.error_message(schema)
"did not contain a minimum number of items #{limit(schema)}"
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/limits/min_length.rb 0000664 0000000 0000000 00000000472 13411675645 0026044 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/limits/length'
module JSON
class Schema
class MinLengthAttribute < LengthLimitAttribute
def self.limit_name
'minLength'
end
def self.error_message(schema)
"was not of a minimum string length of #{limit(schema)}"
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/limits/min_properties.rb 0000664 0000000 0000000 00000000523 13411675645 0026754 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/limits/properties'
module JSON
class Schema
class MinPropertiesAttribute < PropertiesLimitAttribute
def self.limit_name
'minProperties'
end
def self.error_message(schema)
"did not contain a minimum number of properties #{limit(schema)}"
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/limits/minimum.rb 0000664 0000000 0000000 00000000427 13411675645 0025373 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/limits/numeric'
module JSON
class Schema
class MinimumAttribute < NumericLimitAttribute
def self.limit_name
'minimum'
end
def self.exclusive?(schema)
schema['exclusiveMinimum']
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/limits/minimum_inclusive.rb 0000664 0000000 0000000 00000000354 13411675645 0027453 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/limits/minimum'
module JSON
class Schema
class MinimumInclusiveAttribute < MinimumAttribute
def self.exclusive?(schema)
schema['minimumCanEqual'] == false
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/limits/numeric.rb 0000664 0000000 0000000 00000000624 13411675645 0025361 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/limit'
module JSON
class Schema
class NumericLimitAttribute < LimitAttribute
def self.acceptable_type
Numeric
end
def self.error_message(schema)
exclusivity = exclusive?(schema) ? 'exclusively' : 'inclusively'
format("did not have a %s value of %s, %s", limit_name, limit(schema), exclusivity)
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/limits/properties.rb 0000664 0000000 0000000 00000000367 13411675645 0026117 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/limit'
module JSON
class Schema
class PropertiesLimitAttribute < LimitAttribute
def self.acceptable_type
Hash
end
def self.value(data)
data.size
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/maxdecimal.rb 0000664 0000000 0000000 00000001223 13411675645 0024516 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
module JSON
class Schema
class MaxDecimalAttribute < Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
return unless data.is_a?(Numeric)
max_decimal_places = current_schema.schema['maxDecimal']
s = data.to_s.split(".")[1]
if s && s.length > max_decimal_places
message = "The property '#{build_fragment(fragments)}' had more decimal places than the allowed #{max_decimal_places}"
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
end
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/multipleof.rb 0000664 0000000 0000000 00000000306 13411675645 0024573 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/divisibleby'
module JSON
class Schema
class MultipleOfAttribute < DivisibleByAttribute
def self.keyword
'multipleOf'
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/not.rb 0000664 0000000 0000000 00000002155 13411675645 0023217 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
module JSON
class Schema
class NotAttribute < Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
schema = JSON::Schema.new(current_schema.schema['not'],current_schema.uri,validator)
failed = true
errors_copy = processor.validation_errors.clone
begin
schema.validate(data,fragments,processor,options)
# If we're recording errors, we don't throw an exception. Instead, check the errors array length
if options[:record_errors] && errors_copy.length != processor.validation_errors.length
processor.validation_errors.replace(errors_copy)
else
message = "The property '#{build_fragment(fragments)}' of type #{type_of_data(data)} matched the disallowed schema"
failed = false
end
rescue ValidationError
# Yay, we failed validation.
end
unless failed
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
end
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/oneof.rb 0000664 0000000 0000000 00000003616 13411675645 0023530 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
module JSON
class Schema
class OneOfAttribute < Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
errors = Hash.new { |hsh, k| hsh[k] = [] }
validation_error_count = 0
one_of = current_schema.schema['oneOf']
original_data = data.is_a?(Hash) ? data.clone : data
success_data = nil
valid = false
one_of.each_with_index do |element, schema_index|
schema = JSON::Schema.new(element,current_schema.uri,validator)
pre_validation_error_count = validation_errors(processor).count
begin
schema.validate(data,fragments,processor,options)
success_data = data.is_a?(Hash) ? data.clone : data
valid = true
rescue ValidationError
valid = false
end
diff = validation_errors(processor).count - pre_validation_error_count
valid = false if diff > 0
validation_error_count += 1 if !valid
while diff > 0
diff = diff - 1
errors["oneOf ##{schema_index}"].push(validation_errors(processor).pop)
end
data = original_data
end
if validation_error_count == one_of.length - 1
data = success_data
return
end
if validation_error_count == one_of.length
message = "The property '#{build_fragment(fragments)}' of type #{type_of_data(data)} did not match any of the required schemas"
else
message = "The property '#{build_fragment(fragments)}' of type #{type_of_data(data)} matched more than one of the required schemas"
end
validation_error(processor, message, fragments, current_schema, self, options[:record_errors]) if message
validation_errors(processor).last.sub_errors = errors if message
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/pattern.rb 0000664 0000000 0000000 00000001163 13411675645 0024072 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
module JSON
class Schema
class PatternAttribute < Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
return unless data.is_a?(String)
pattern = current_schema.schema['pattern']
regexp = Regexp.new(pattern)
unless regexp.match(data)
message = "The property '#{build_fragment(fragments)}' value #{data.inspect} did not match the regex '#{pattern}'"
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
end
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/patternproperties.rb 0000664 0000000 0000000 00000001345 13411675645 0026211 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
module JSON
class Schema
class PatternPropertiesAttribute < Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
return unless data.is_a?(Hash)
current_schema.schema['patternProperties'].each do |property, property_schema|
regexp = Regexp.new(property)
# Check each key in the data hash to see if it matches the regex
data.each do |key, value|
next unless regexp.match(key)
schema = JSON::Schema.new(property_schema, current_schema.uri, validator)
schema.validate(data[key], fragments + [key], processor, options)
end
end
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/properties.rb 0000664 0000000 0000000 00000004523 13411675645 0024614 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
module JSON
class Schema
class PropertiesAttribute < Attribute
def self.required?(schema, options)
schema.fetch('required') { options[:strict] }
end
def self.validate(current_schema, data, fragments, processor, validator, options = {})
return unless data.is_a?(Hash)
schema = current_schema.schema
schema['properties'].each do |property, property_schema|
property = property.to_s
if !data.key?(property) &&
options[:insert_defaults] &&
property_schema.has_key?('default') &&
!property_schema['readonly']
default = property_schema['default']
data[property] = default.is_a?(Hash) ? default.clone : default
end
if required?(property_schema, options) && !data.has_key?(property)
message = "The property '#{build_fragment(fragments)}' did not contain a required property of '#{property}'"
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
end
if data.has_key?(property)
expected_schema = JSON::Schema.new(property_schema, current_schema.uri, validator)
expected_schema.validate(data[property], fragments + [property], processor, options)
end
end
# When strict is true, ensure no undefined properties exist in the data
return unless options[:strict] == true && !schema.key?('additionalProperties')
diff = data.select do |k, v|
k = k.to_s
if schema.has_key?('patternProperties')
match = false
schema['patternProperties'].each do |property, property_schema|
regexp = Regexp.new(property)
if regexp.match(k)
match = true
break
end
end
!schema['properties'].has_key?(k) && !match
else
!schema['properties'].has_key?(k)
end
end
if diff.size > 0
properties = diff.keys.join(', ')
message = "The property '#{build_fragment(fragments)}' contained undefined properties: '#{properties}'"
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
end
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/properties_optional.rb 0000664 0000000 0000000 00000001717 13411675645 0026523 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
module JSON
class Schema
class PropertiesOptionalAttribute < Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
return unless data.is_a?(Hash)
schema = current_schema.schema
schema['properties'].each do |property, property_schema|
property = property.to_s
if !property_schema['optional'] && !data.key?(property)
message = "The property '#{build_fragment(fragments)}' did not contain a required property of '#{property}'"
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
end
if data.has_key?(property)
expected_schema = JSON::Schema.new(property_schema, current_schema.uri, validator)
expected_schema.validate(data[property], fragments + [property], processor, options)
end
end
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/properties_v4.rb 0000664 0000000 0000000 00000000564 13411675645 0025226 0 ustar 00root root 0000000 0000000 require 'json-schema/attributes/properties'
module JSON
class Schema
class PropertiesV4Attribute < PropertiesAttribute
# draft4 relies on its own RequiredAttribute validation at a higher level, rather than
# as an attribute of individual properties.
def self.required?(schema, options)
options[:strict] == true
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/ref.rb 0000664 0000000 0000000 00000004460 13411675645 0023174 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
require 'json-schema/errors/schema_error'
require 'json-schema/util/uri'
module JSON
class Schema
class RefAttribute < Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
uri,schema = get_referenced_uri_and_schema(current_schema.schema, current_schema, validator)
if schema
schema.validate(data, fragments, processor, options)
elsif uri
message = "The referenced schema '#{uri.to_s}' cannot be found"
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
else
message = "The property '#{build_fragment(fragments)}' was not a valid schema"
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
end
end
def self.get_referenced_uri_and_schema(s, current_schema, validator)
uri,schema = nil,nil
temp_uri = JSON::Util::URI.normalize_ref(s['$ref'], current_schema.uri)
# Grab the parent schema from the schema list
schema_key = temp_uri.to_s.split("#")[0] + "#"
ref_schema = JSON::Validator.schema_for_uri(schema_key)
if ref_schema
# Perform fragment resolution to retrieve the appropriate level for the schema
target_schema = ref_schema.schema
fragments = JSON::Util::URI.parse(JSON::Util::URI.unescape_uri(temp_uri)).fragment.split("/")
fragment_path = ''
fragments.each do |fragment|
if fragment && fragment != ''
fragment = fragment.gsub('~0', '~').gsub('~1', '/')
if target_schema.is_a?(Array)
target_schema = target_schema[fragment.to_i]
else
target_schema = target_schema[fragment]
end
fragment_path = fragment_path + "/#{fragment}"
if target_schema.nil?
raise SchemaError.new("The fragment '#{fragment_path}' does not exist on schema #{ref_schema.uri.to_s}")
end
end
end
# We have the schema finally, build it and validate!
uri = temp_uri
schema = JSON::Schema.new(target_schema,temp_uri,validator)
end
[uri,schema]
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/required.rb 0000664 0000000 0000000 00000002030 13411675645 0024227 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
module JSON
class Schema
class RequiredAttribute < Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
return unless data.is_a?(Hash)
schema = current_schema.schema
defined_properties = schema['properties']
schema['required'].each do |property, property_schema|
next if data.has_key?(property.to_s)
prop_defaults = options[:insert_defaults] &&
defined_properties &&
defined_properties[property] &&
!defined_properties[property]["default"].nil? &&
!defined_properties[property]["readonly"]
if !prop_defaults
message = "The property '#{build_fragment(fragments)}' did not contain a required property of '#{property}'"
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
end
end
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/type.rb 0000664 0000000 0000000 00000005705 13411675645 0023404 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
module JSON
class Schema
class TypeAttribute < Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
union = true
if options[:disallow]
types = current_schema.schema['disallow']
else
types = current_schema.schema['type']
end
if !types.is_a?(Array)
types = [types]
union = false
end
valid = false
# Create a hash to hold errors that are generated during union validation
union_errors = Hash.new { |hsh, k| hsh[k] = [] }
types.each_with_index do |type, type_index|
if type.is_a?(String)
valid = data_valid_for_type?(data, type)
elsif type.is_a?(Hash) && union
# Validate as a schema
schema = JSON::Schema.new(type,current_schema.uri,validator)
# We're going to add a little cruft here to try and maintain any validation errors that occur in this union type
# We'll handle this by keeping an error count before and after validation, extracting those errors and pushing them onto a union error
pre_validation_error_count = validation_errors(processor).count
begin
schema.validate(data,fragments,processor,options.merge(:disallow => false))
valid = true
rescue ValidationError
# We don't care that these schemas don't validate - we only care that one validated
end
diff = validation_errors(processor).count - pre_validation_error_count
valid = false if diff > 0
while diff > 0
diff = diff - 1
union_errors["type ##{type_index}"].push(validation_errors(processor).pop)
end
end
break if valid
end
if options[:disallow]
return if !valid
message = "The property '#{build_fragment(fragments)}' matched one or more of the following types: #{list_types(types)}"
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
elsif !valid
if union
message = "The property '#{build_fragment(fragments)}' of type #{type_of_data(data)} did not match one or more of the following types: #{list_types(types)}"
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
validation_errors(processor).last.sub_errors = union_errors
else
message = "The property '#{build_fragment(fragments)}' of type #{type_of_data(data)} did not match the following type: #{list_types(types)}"
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
end
end
end
def self.list_types(types)
types.map { |type| type.is_a?(String) ? type : '(schema)' }.join(', ')
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/type_v4.rb 0000664 0000000 0000000 00000001612 13411675645 0024006 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
module JSON
class Schema
class TypeV4Attribute < Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
union = true
types = current_schema.schema['type']
if !types.is_a?(Array)
types = [types]
union = false
end
return if types.any? { |type| data_valid_for_type?(data, type) }
types = types.map { |type| type.is_a?(String) ? type : '(schema)' }.join(', ')
message = format(
"The property '%s' of type %s did not match %s: %s",
build_fragment(fragments),
type_of_data(data),
union ? 'one or more of the following types' : 'the following type',
types
)
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/attributes/uniqueitems.rb 0000664 0000000 0000000 00000000776 13411675645 0024776 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
module JSON
class Schema
class UniqueItemsAttribute < Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
return unless data.is_a?(Array)
if data.clone.uniq!
message = "The property '#{build_fragment(fragments)}' contained duplicated array values"
validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
end
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/errors/ 0000775 0000000 0000000 00000000000 13411675645 0021215 5 ustar 00root root 0000000 0000000 ruby-json-schema-2.8.1/lib/json-schema/errors/custom_format_error.rb 0000664 0000000 0000000 00000000131 13411675645 0025630 0 ustar 00root root 0000000 0000000 module JSON
class Schema
class CustomFormatError < StandardError
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/errors/json_load_error.rb 0000664 0000000 0000000 00000000125 13411675645 0024721 0 ustar 00root root 0000000 0000000 module JSON
class Schema
class JsonLoadError < StandardError
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/errors/json_parse_error.rb 0000664 0000000 0000000 00000000126 13411675645 0025115 0 ustar 00root root 0000000 0000000 module JSON
class Schema
class JsonParseError < StandardError
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/errors/schema_error.rb 0000664 0000000 0000000 00000000123 13411675645 0024207 0 ustar 00root root 0000000 0000000 module JSON
class Schema
class SchemaError < StandardError
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/errors/schema_parse_error.rb 0000664 0000000 0000000 00000000163 13411675645 0025405 0 ustar 00root root 0000000 0000000 require 'json/common'
module JSON
class Schema
class SchemaParseError < JSON::ParserError
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/errors/uri_error.rb 0000664 0000000 0000000 00000000120 13411675645 0023543 0 ustar 00root root 0000000 0000000 module JSON
class Schema
class UriError < StandardError
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/errors/validation_error.rb 0000664 0000000 0000000 00000003137 13411675645 0025111 0 ustar 00root root 0000000 0000000 module JSON
class Schema
class ValidationError < StandardError
INDENT = " "
attr_accessor :fragments, :schema, :failed_attribute, :sub_errors, :message
def initialize(message, fragments, failed_attribute, schema)
@fragments = fragments.clone
@schema = schema
@sub_errors = {}
@failed_attribute = failed_attribute
@message = message
super(message_with_schema)
end
def to_string(subschema_level = 0)
if @sub_errors.empty?
subschema_level == 0 ? message_with_schema : message
else
messages = ["#{message}. The schema specific errors were:\n"]
@sub_errors.each do |subschema, errors|
messages.push "- #{subschema}:"
messages.concat Array(errors).map { |e| "#{INDENT}- #{e.to_string(subschema_level + 1)}" }
end
messages.map { |m| (INDENT * subschema_level) + m }.join("\n")
end
end
def to_hash
base = {:schema => @schema.uri, :fragment => ::JSON::Schema::Attribute.build_fragment(fragments), :message => message_with_schema, :failed_attribute => @failed_attribute.to_s.split(":").last.split("Attribute").first}
if !@sub_errors.empty?
base[:errors] = @sub_errors.inject({}) do |hsh, (subschema, errors)|
subschema_sym = subschema.downcase.gsub(/\W+/, '_').to_sym
hsh[subschema_sym] = Array(errors).map{|e| e.to_hash}
hsh
end
end
base
end
def message_with_schema
"#{message} in schema #{schema.uri}"
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/schema.rb 0000664 0000000 0000000 00000003300 13411675645 0021462 0 ustar 00root root 0000000 0000000 require 'pathname'
module JSON
class Schema
attr_accessor :schema, :uri, :validator
def initialize(schema,uri,parent_validator=nil)
@schema = schema
@uri = uri
# If there is an ID on this schema, use it to generate the URI
if @schema['id'] && @schema['id'].kind_of?(String)
temp_uri = JSON::Util::URI.parse(@schema['id'])
if temp_uri.relative?
temp_uri = uri.join(temp_uri)
end
@uri = temp_uri
end
@uri = JSON::Util::URI.strip_fragment(@uri)
# If there is a $schema on this schema, use it to determine which validator to use
if @schema['$schema']
@validator = JSON::Validator.validator_for_uri(@schema['$schema'])
elsif parent_validator
@validator = parent_validator
else
@validator = JSON::Validator.default_validator
end
end
def validate(data, fragments, processor, options = {})
@validator.validate(self, data, fragments, processor, options)
end
def self.stringify(schema)
case schema
when Hash then
Hash[schema.map { |key, value| [key.to_s, stringify(schema[key])] }]
when Array then
schema.map do |schema_item|
stringify(schema_item)
end
when Symbol then
schema.to_s
else
schema
end
end
# @return [JSON::Schema] a new schema matching an array whose items all match this schema.
def to_array_schema
array_schema = { 'type' => 'array', 'items' => schema }
array_schema['$schema'] = schema['$schema'] unless schema['$schema'].nil?
self.class.new(array_schema, uri, validator)
end
def to_s
@schema.to_json
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/schema/ 0000775 0000000 0000000 00000000000 13411675645 0021141 5 ustar 00root root 0000000 0000000 ruby-json-schema-2.8.1/lib/json-schema/schema/reader.rb 0000664 0000000 0000000 00000010671 13411675645 0022735 0 ustar 00root root 0000000 0000000 require 'open-uri'
require 'pathname'
module JSON
class Schema
# Base for any reading exceptions encountered by {JSON::Schema::Reader}
class ReadError < StandardError
# @return [String] the requested schema location which was refused
attr_reader :location
# @return [Symbol] either +:uri+ or +:file+
attr_reader :type
def initialize(location, type)
@location = location
@type = type
super(error_message)
end
private
def type_string
type == :uri ? 'URI' : type.to_s
end
end
# Raised by {JSON::Schema::Reader} when one of its settings indicate
# a schema should not be read.
class ReadRefused < ReadError
private
def error_message
"Read of #{type_string} at #{location} refused"
end
end
# Raised by {JSON::Schema::Reader} when an attempt to read a schema fails
class ReadFailed < ReadError
private
def error_message
"Read of #{type_string} at #{location} failed"
end
end
# When an unregistered schema is encountered, the {JSON::Schema::Reader} is
# used to fetch its contents and register it with the {JSON::Validator}.
#
# This default reader will read schemas from the filesystem or from a URI.
class Reader
# The behavior of the schema reader can be controlled by providing
# callbacks to determine whether to permit reading referenced schemas.
# The options +accept_uri+ and +accept_file+ should be procs which
# accept a +URI+ or +Pathname+ object, and return a boolean value
# indicating whether to read the referenced schema.
#
# URIs using the +file+ scheme will be normalized into +Pathname+ objects
# and passed to the +accept_file+ callback.
#
# @param options [Hash]
# @option options [Boolean, #call] accept_uri (true)
# @option options [Boolean, #call] accept_file (true)
#
# @example Reject all unregistered schemas
# JSON::Validator.schema_reader = JSON::Schema::Reader.new(
# :accept_uri => false,
# :accept_file => false
# )
#
# @example Only permit URIs from certain hosts
# JSON::Validator.schema_reader = JSON::Schema::Reader.new(
# :accept_file => false,
# :accept_uri => proc { |uri| ['mycompany.com', 'json-schema.org'].include?(uri.host) }
# )
def initialize(options = {})
@accept_uri = options.fetch(:accept_uri, true)
@accept_file = options.fetch(:accept_file, true)
end
# @param location [#to_s] The location from which to read the schema
# @return [JSON::Schema]
# @raise [JSON::Schema::ReadRefused] if +accept_uri+ or +accept_file+
# indicated the schema could not be read
# @raise [JSON::Schema::ParseError] if the schema was not a valid JSON object
# @raise [JSON::Schema::ReadFailed] if reading the location was acceptable but the
# attempt to retrieve it failed
def read(location)
uri = JSON::Util::URI.parse(location.to_s)
body = if uri.scheme.nil? || uri.scheme == 'file'
uri = JSON::Util::URI.file_uri(uri)
read_file(Pathname.new(uri.path).expand_path)
else
read_uri(uri)
end
JSON::Schema.new(JSON::Validator.parse(body), uri)
end
# @param uri [Addressable::URI]
# @return [Boolean]
def accept_uri?(uri)
if @accept_uri.respond_to?(:call)
@accept_uri.call(uri)
else
@accept_uri
end
end
# @param pathname [Pathname]
# @return [Boolean]
def accept_file?(pathname)
if @accept_file.respond_to?(:call)
@accept_file.call(pathname)
else
@accept_file
end
end
private
def read_uri(uri)
if accept_uri?(uri)
open(uri.to_s).read
else
raise JSON::Schema::ReadRefused.new(uri.to_s, :uri)
end
rescue OpenURI::HTTPError, SocketError
raise JSON::Schema::ReadFailed.new(uri.to_s, :uri)
end
def read_file(pathname)
if accept_file?(pathname)
File.read(JSON::Util::URI.unescaped_path(pathname.to_s))
else
raise JSON::Schema::ReadRefused.new(pathname.to_s, :file)
end
rescue Errno::ENOENT
raise JSON::Schema::ReadFailed.new(pathname.to_s, :file)
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/schema/validator.rb 0000664 0000000 0000000 00000002240 13411675645 0023451 0 ustar 00root root 0000000 0000000 module JSON
class Schema
class Validator
attr_accessor :attributes, :formats, :uri, :names
attr_reader :default_formats
def initialize()
@attributes = {}
@formats = {}
@default_formats = {}
@uri = nil
@names = []
@metaschema_name = ''
end
def extend_schema_definition(schema_uri)
warn "[DEPRECATION NOTICE] The preferred way to extend a Validator is by subclassing, rather than #extend_schema_definition. This method will be removed in version >= 3."
validator = JSON::Validator.validator_for_uri(schema_uri)
@attributes.merge!(validator.attributes)
end
def validate(current_schema, data, fragments, processor, options = {})
current_schema.schema.each do |attr_name,attribute|
if @attributes.has_key?(attr_name.to_s)
@attributes[attr_name.to_s].validate(current_schema, data, fragments, processor, self, options)
end
end
data
end
def metaschema
resources = File.expand_path('../../../../resources', __FILE__)
File.join(resources, @metaschema_name)
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/util/ 0000775 0000000 0000000 00000000000 13411675645 0020656 5 ustar 00root root 0000000 0000000 ruby-json-schema-2.8.1/lib/json-schema/util/array_set.rb 0000664 0000000 0000000 00000001011 13411675645 0023165 0 ustar 00root root 0000000 0000000 require 'set'
# This is a hack that I don't want to ever use anywhere else or repeat EVER, but we need enums to be
# an Array to pass schema validation. But we also want fast lookup!
class ArraySet < Array
def include?(obj)
if !defined? @values
@values = Set.new
self.each { |x| @values << convert_to_float_if_numeric(x) }
end
@values.include?(convert_to_float_if_numeric(obj))
end
private
def convert_to_float_if_numeric(value)
value.is_a?(Numeric) ? value.to_f : value
end
end
ruby-json-schema-2.8.1/lib/json-schema/util/uri.rb 0000664 0000000 0000000 00000005430 13411675645 0022004 0 ustar 00root root 0000000 0000000 require 'addressable/uri'
module JSON
module Util
module URI
SUPPORTED_PROTOCOLS = %w(http https ftp tftp sftp ssh svn+ssh telnet nntp gopher wais ldap prospero)
def self.normalized_uri(uri, base_path = Dir.pwd)
@normalize_cache ||= {}
normalized_uri = @normalize_cache[uri]
if !normalized_uri
normalized_uri = parse(uri)
# Check for absolute path
if normalized_uri.relative?
data = normalized_uri
data = File.join(base_path, data) if data.path[0,1] != "/"
normalized_uri = file_uri(data)
end
@normalize_cache[uri] = normalized_uri.freeze
end
normalized_uri
end
def self.absolutize_ref(ref, base)
ref_uri = strip_fragment(ref.dup)
return ref_uri if ref_uri.absolute?
return parse(base) if ref_uri.path.empty?
uri = strip_fragment(base.dup).join(ref_uri.path)
normalized_uri(uri)
end
def self.normalize_ref(ref, base)
ref_uri = parse(ref)
base_uri = parse(base)
ref_uri.defer_validation do
if ref_uri.relative?
ref_uri.merge!(base_uri)
# Check for absolute path
path, fragment = ref.to_s.split("#")
if path.nil? || path == ''
ref_uri.path = base_uri.path
elsif path[0,1] == "/"
ref_uri.path = Pathname.new(path).cleanpath.to_s
else
ref_uri.join!(path)
end
ref_uri.fragment = fragment
end
ref_uri.fragment = "" if ref_uri.fragment.nil? || ref_uri.fragment.empty?
end
ref_uri
end
def self.parse(uri)
if uri.is_a?(Addressable::URI)
return uri.dup
else
@parse_cache ||= {}
parsed_uri = @parse_cache[uri]
if parsed_uri
parsed_uri.dup
else
@parse_cache[uri] = Addressable::URI.parse(uri)
end
end
rescue Addressable::URI::InvalidURIError => e
raise JSON::Schema::UriError.new(e.message)
end
def self.strip_fragment(uri)
parsed_uri = parse(uri)
if parsed_uri.fragment.nil? || parsed_uri.fragment.empty?
parsed_uri
else
parsed_uri.merge(:fragment => "")
end
end
def self.file_uri(uri)
parsed_uri = parse(uri)
Addressable::URI.convert_path(parsed_uri.path)
end
def self.unescape_uri(uri)
Addressable::URI.unescape(uri)
end
def self.unescaped_path(uri)
parsed_uri = parse(uri)
Addressable::URI.unescape(parsed_uri.path)
end
def self.clear_cache
@parse_cache = {}
@normalize_cache = {}
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/util/uuid.rb 0000664 0000000 0000000 00000020427 13411675645 0022156 0 ustar 00root root 0000000 0000000 #!/usr/bin/env ruby
### http://mput.dip.jp/mput/uuid.txt
# Copyright(c) 2005 URABE, Shyouhei.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this code, to deal in the code without restriction, including without
# limitation the rights to use, copy, modify, merge, publish, distribute,
# sublicense, and/or sell copies of the code, and to permit persons to whom the
# code is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the code.
#
# THE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHOR OR COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE CODE OR THE USE OR OTHER DEALINGS IN THE
# CODE.
#
# 2009-02-20: Modified by Pablo Lorenzoni to correctly
# include the version in the raw_bytes.
require 'digest/md5'
require 'digest/sha1'
require 'tmpdir'
module JSON
module Util
# Pure ruby UUID generator, which is compatible with RFC4122
UUID = Struct.new :raw_bytes
class UUID
private_class_method :new
class << self
def mask19 v, str # :nodoc
nstr = str.bytes.to_a
version = [0, 16, 32, 48, 64, 80][v]
nstr[6] &= 0b00001111
nstr[6] |= version
# nstr[7] &= 0b00001111
# nstr[7] |= 0b01010000
nstr[8] &= 0b00111111
nstr[8] |= 0b10000000
str = ''
nstr.each { |s| str << s.chr }
str
end
def mask18 v, str # :nodoc
version = [0, 16, 32, 48, 64, 80][v]
str[6] &= 0b00001111
str[6] |= version
# str[7] &= 0b00001111
# str[7] |= 0b01010000
str[8] &= 0b00111111
str[8] |= 0b10000000
str
end
def mask v, str
if RUBY_VERSION >= "1.9.0"
return mask19 v, str
else
return mask18 v, str
end
end
private :mask, :mask18, :mask19
# UUID generation using SHA1. Recommended over create_md5.
# Namespace object is another UUID, some of them are pre-defined below.
def create_sha1 str, namespace
sha1 = Digest::SHA1.new
sha1.update namespace.raw_bytes
sha1.update str
sum = sha1.digest
raw = mask 5, sum[0..15]
ret = new raw
ret.freeze
ret
end
alias :create_v5 :create_sha1
# UUID generation using MD5 (for backward compat.)
def create_md5 str, namespace
md5 = Digest::MD5.new
md5.update namespace.raw_bytes
md5.update str
sum = md5.digest
raw = mask 3, sum[0..16]
ret = new raw
ret.freeze
ret
end
alias :create_v3 :create_md5
# UUID generation using random-number generator. From it's random
# nature, there's no warranty that the created ID is really universaly
# unique.
def create_random
rnd = [
rand(0x100000000),
rand(0x100000000),
rand(0x100000000),
rand(0x100000000),
].pack "N4"
raw = mask 4, rnd
ret = new raw
ret.freeze
ret
end
alias :create_v4 :create_random
def read_state fp # :nodoc:
fp.rewind
Marshal.load fp.read
end
def write_state fp, c, m # :nodoc:
fp.rewind
str = Marshal.dump [c, m]
fp.write str
end
private :read_state, :write_state
STATE_FILE = 'ruby-uuid'
# create the "version 1" UUID with current system clock, current UTC
# timestamp, and the IEEE 802 address (so-called MAC address).
#
# Speed notice: it's slow. It writes some data into hard drive on every
# invokation. If you want to speed this up, try remounting tmpdir with a
# memory based filesystem (such as tmpfs). STILL slow? then no way but
# rewrite it with c :)
def create clock=nil, time=nil, mac_addr=nil
c = t = m = nil
Dir.chdir Dir.tmpdir do
unless FileTest.exist? STATE_FILE then
# Generate a pseudo MAC address because we have no pure-ruby way
# to know the MAC address of the NIC this system uses. Note
# that cheating with pseudo arresses here is completely legal:
# see Section 4.5 of RFC4122 for details.
sha1 = Digest::SHA1.new
256.times do
r = [rand(0x100000000)].pack "N"
sha1.update r
end
str = sha1.digest
r = rand 14 # 20-6
node = str[r, 6] || str
if RUBY_VERSION >= "1.9.0"
nnode = node.bytes.to_a
nnode[0] |= 0x01
node = ''
nnode.each { |s| node << s.chr }
else
node[0] |= 0x01 # multicast bit
end
k = rand 0x40000
open STATE_FILE, 'w' do |fp|
fp.flock IO::LOCK_EX
write_state fp, k, node
fp.chmod 0o777 # must be world writable
end
end
open STATE_FILE, 'r+' do |fp|
fp.flock IO::LOCK_EX
c, m = read_state fp
c = clock % 0x4000 if clock
m = mac_addr if mac_addr
t = time
if t.nil? then
# UUID epoch is 1582/Oct/15
tt = Time.now
t = tt.to_i*10000000 + tt.tv_usec*10 + 0x01B21DD213814000
end
c = c.succ # important; increment here
write_state fp, c, m
end
end
tl = t & 0xFFFF_FFFF
tm = t >> 32
tm = tm & 0xFFFF
th = t >> 48
th = th & 0x0FFF
th = th | 0x1000
cl = c & 0xFF
ch = c & 0x3F00
ch = ch >> 8
ch = ch | 0x80
pack tl, tm, th, cl, ch, m
end
alias :create_v1 :create
# A simple GUID parser: just ignores unknown characters and convert
# hexadecimal dump into 16-octet object.
def parse obj
str = obj.to_s.sub %r/\Aurn:uuid:/, ''
str.gsub! %r/[^0-9A-Fa-f]/, ''
raw = str[0..31].lines.to_a.pack 'H*'
ret = new raw
ret.freeze
ret
end
# The 'primitive constructor' of this class
# Note UUID.pack(uuid.unpack) == uuid
def pack tl, tm, th, ch, cl, n
raw = [tl, tm, th, ch, cl, n].pack "NnnCCa6"
ret = new raw
ret.freeze
ret
end
end
# The 'primitive deconstructor', or the dual to pack.
# Note UUID.pack(uuid.unpack) == uuid
def unpack
raw_bytes.unpack "NnnCCa6"
end
# Generate the string representation (a.k.a GUID) of this UUID
def to_s
a = unpack
tmp = a[-1].unpack 'C*'
a[-1] = sprintf '%02x%02x%02x%02x%02x%02x', *tmp
"%08x-%04x-%04x-%02x%02x-%s" % a
end
alias guid to_s
# Convert into a RFC4122-comforming URN representation
def to_uri
"urn:uuid:" + self.to_s
end
alias urn to_uri
# Convert into 128-bit unsigned integer
def to_int
tmp = self.raw_bytes.unpack "C*"
tmp.inject do |r, i|
r * 256 | i
end
end
alias to_i to_int
# Gets the version of this UUID
# returns nil if bad version
def version
a = unpack
v = (a[2] & 0xF000).to_s(16)[0].chr.to_i
return v if (1..5).include? v
return nil
end
# Two UUIDs are said to be equal if and only if their (byte-order
# canonicalized) integer representations are equivallent. Refer RFC4122 for
# details.
def == other
to_i == other.to_i
end
include Comparable
# UUIDs are comparable (don't know what benefits are there, though).
def <=> other
to_s <=> other.to_s
end
# Pre-defined UUID Namespaces described in RFC4122 Appendix C.
NameSpace_DNS = parse "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
NameSpace_URL = parse "6ba7b811-9dad-11d1-80b4-00c04fd430c8"
NameSpace_OID = parse "6ba7b812-9dad-11d1-80b4-00c04fd430c8"
NameSpace_X500 = parse "6ba7b814-9dad-11d1-80b4-00c04fd430c8"
# The Nil UUID in RFC4122 Section 4.1.7
Nil = parse "00000000-0000-0000-0000-000000000000"
end
end
end ruby-json-schema-2.8.1/lib/json-schema/validator.rb 0000664 0000000 0000000 00000046646 13411675645 0022233 0 ustar 00root root 0000000 0000000 require 'open-uri'
require 'pathname'
require 'bigdecimal'
require 'digest/sha1'
require 'date'
require 'thread'
require 'yaml'
require 'json-schema/schema/reader'
require 'json-schema/errors/schema_error'
require 'json-schema/errors/schema_parse_error'
require 'json-schema/errors/json_load_error'
require 'json-schema/errors/json_parse_error'
require 'json-schema/util/uri'
module JSON
class Validator
@@schemas = {}
@@cache_schemas = true
@@default_opts = {
:list => false,
:version => nil,
:validate_schema => false,
:record_errors => false,
:errors_as_objects => false,
:insert_defaults => false,
:clear_cache => false,
:strict => false,
:parse_data => true
}
@@validators = {}
@@default_validator = nil
@@available_json_backends = []
@@json_backend = nil
@@serializer = nil
@@mutex = Mutex.new
def initialize(schema_data, data, opts={})
@options = @@default_opts.clone.merge(opts)
@errors = []
validator = self.class.validator_for_name(@options[:version])
@options[:version] = validator
@options[:schema_reader] ||= self.class.schema_reader
@validation_options = @options[:record_errors] ? {:record_errors => true} : {}
@validation_options[:insert_defaults] = true if @options[:insert_defaults]
@validation_options[:strict] = true if @options[:strict] == true
@validation_options[:clear_cache] = true if !@@cache_schemas || @options[:clear_cache]
@@mutex.synchronize { @base_schema = initialize_schema(schema_data) }
@original_data = data
@data = initialize_data(data)
@@mutex.synchronize { build_schemas(@base_schema) }
# validate the schema, if requested
if @options[:validate_schema]
if @base_schema.schema["$schema"]
base_validator = self.class.validator_for_name(@base_schema.schema["$schema"])
end
metaschema = base_validator ? base_validator.metaschema : validator.metaschema
# Don't clear the cache during metaschema validation!
self.class.validate!(metaschema, @base_schema.schema, {:clear_cache => false})
end
# If the :fragment option is set, try and validate against the fragment
if opts[:fragment]
@base_schema = schema_from_fragment(@base_schema, opts[:fragment])
end
end
def schema_from_fragment(base_schema, fragment)
schema_uri = base_schema.uri
fragments = fragment.split("/")
# ensure the first element was a hash, per the fragment spec
if fragments.shift != "#"
raise JSON::Schema::SchemaError.new("Invalid fragment syntax in :fragment option")
end
fragments.each do |f|
if base_schema.is_a?(JSON::Schema) #test if fragment is a JSON:Schema instance
if !base_schema.schema.has_key?(f)
raise JSON::Schema::SchemaError.new("Invalid fragment resolution for :fragment option")
end
base_schema = base_schema.schema[f]
elsif base_schema.is_a?(Hash)
if !base_schema.has_key?(f)
raise JSON::Schema::SchemaError.new("Invalid fragment resolution for :fragment option")
end
base_schema = JSON::Schema.new(base_schema[f],schema_uri,@options[:version])
elsif base_schema.is_a?(Array)
if base_schema[f.to_i].nil?
raise JSON::Schema::SchemaError.new("Invalid fragment resolution for :fragment option")
end
base_schema = JSON::Schema.new(base_schema[f.to_i],schema_uri,@options[:version])
else
raise JSON::Schema::SchemaError.new("Invalid schema encountered when resolving :fragment option")
end
end
if @options[:list]
base_schema.to_array_schema
elsif base_schema.is_a?(Hash)
JSON::Schema.new(base_schema, schema_uri, @options[:version])
else
base_schema
end
end
# Run a simple true/false validation of data against a schema
def validate
@base_schema.validate(@data,[],self,@validation_options)
if @options[:record_errors]
if @options[:errors_as_objects]
@errors.map{|e| e.to_hash}
else
@errors.map{|e| e.to_string}
end
else
true
end
ensure
if @validation_options[:clear_cache] == true
self.class.clear_cache
end
if @validation_options[:insert_defaults]
self.class.merge_missing_values(@data, @original_data)
end
end
def load_ref_schema(parent_schema, ref)
schema_uri = JSON::Util::URI.absolutize_ref(ref, parent_schema.uri)
return true if self.class.schema_loaded?(schema_uri)
validator = self.class.validator_for_uri(schema_uri, false)
schema_uri = JSON::Util::URI.file_uri(validator.metaschema) if validator
schema = @options[:schema_reader].read(schema_uri)
self.class.add_schema(schema)
build_schemas(schema)
end
# Build all schemas with IDs, mapping out the namespace
def build_schemas(parent_schema)
schema = parent_schema.schema
# Build ref schemas if they exist
if schema["$ref"]
load_ref_schema(parent_schema, schema["$ref"])
end
case schema["extends"]
when String
load_ref_schema(parent_schema, schema["extends"])
when Array
schema['extends'].each do |type|
handle_schema(parent_schema, type)
end
end
# Check for schemas in union types
["type", "disallow"].each do |key|
if schema[key].is_a?(Array)
schema[key].each do |type|
if type.is_a?(Hash)
handle_schema(parent_schema, type)
end
end
end
end
# Schema properties whose values are objects, the values of which
# are themselves schemas.
%w[definitions properties patternProperties].each do |key|
next unless value = schema[key]
value.each do |k, inner_schema|
handle_schema(parent_schema, inner_schema)
end
end
# Schema properties whose values are themselves schemas.
%w[additionalProperties additionalItems dependencies extends].each do |key|
next unless schema[key].is_a?(Hash)
handle_schema(parent_schema, schema[key])
end
# Schema properties whose values may be an array of schemas.
%w[allOf anyOf oneOf not].each do |key|
next unless value = schema[key]
Array(value).each do |inner_schema|
handle_schema(parent_schema, inner_schema)
end
end
# Items are always schemas
if schema["items"]
items = schema["items"].clone
items = [items] unless items.is_a?(Array)
items.each do |item|
handle_schema(parent_schema, item)
end
end
# Convert enum to a ArraySet
if schema["enum"].is_a?(Array)
schema["enum"] = ArraySet.new(schema["enum"])
end
end
# Either load a reference schema or create a new schema
def handle_schema(parent_schema, obj)
if obj.is_a?(Hash)
schema_uri = parent_schema.uri.dup
schema = JSON::Schema.new(obj, schema_uri, parent_schema.validator)
if obj['id']
self.class.add_schema(schema)
end
build_schemas(schema)
end
end
def validation_error(error)
@errors.push(error)
end
def validation_errors
@errors
end
class << self
def validate(schema, data,opts={})
begin
validate!(schema, data, opts)
rescue JSON::Schema::ValidationError, JSON::Schema::SchemaError
return false
end
end
def validate_json(schema, data, opts={})
validate(schema, data, opts.merge(:json => true))
end
def validate_uri(schema, data, opts={})
validate(schema, data, opts.merge(:uri => true))
end
def validate!(schema, data,opts={})
validator = new(schema, data, opts)
validator.validate
end
def validate2(schema, data, opts={})
warn "[DEPRECATION NOTICE] JSON::Validator#validate2 has been replaced by JSON::Validator#validate! and will be removed in version >= 3. Please use the #validate! method instead."
validate!(schema, data, opts)
end
def validate_json!(schema, data, opts={})
validate!(schema, data, opts.merge(:json => true))
end
def validate_uri!(schema, data, opts={})
validate!(schema, data, opts.merge(:uri => true))
end
def fully_validate(schema, data, opts={})
validate!(schema, data, opts.merge(:record_errors => true))
end
def fully_validate_schema(schema, opts={})
data = schema
schema = validator_for_name(opts[:version]).metaschema
fully_validate(schema, data, opts)
end
def fully_validate_json(schema, data, opts={})
fully_validate(schema, data, opts.merge(:json => true))
end
def fully_validate_uri(schema, data, opts={})
fully_validate(schema, data, opts.merge(:uri => true))
end
def schema_reader
@@schema_reader ||= JSON::Schema::Reader.new
end
def schema_reader=(reader)
@@schema_reader = reader
end
def clear_cache
@@schemas = {}
JSON::Util::URI.clear_cache
end
def schemas
@@schemas
end
def add_schema(schema)
@@schemas[schema_key_for(schema.uri)] ||= schema
end
def schema_for_uri(uri)
# We only store normalized uris terminated with fragment #, so we can try whether
# normalization can be skipped
@@schemas[uri] || @@schemas[schema_key_for(uri)]
end
def schema_loaded?(schema_uri)
!schema_for_uri(schema_uri).nil?
end
def schema_key_for(uri)
key = Util::URI.normalized_uri(uri).to_s
key.end_with?('#') ? key : "#{key}#"
end
def cache_schemas=(val)
warn "[DEPRECATION NOTICE] Schema caching is now a validation option. Schemas will still be cached if this is set to true, but this method will be removed in version >= 3. Please use the :clear_cache validation option instead."
@@cache_schemas = val == true ? true : false
end
def validators
@@validators
end
def default_validator
@@default_validator
end
def validator_for_uri(schema_uri, raise_not_found=true)
return default_validator unless schema_uri
u = JSON::Util::URI.parse(schema_uri)
validator = validators["#{u.scheme}://#{u.host}#{u.path}"]
if validator.nil? && raise_not_found
raise JSON::Schema::SchemaError.new("Schema not found: #{schema_uri}")
else
validator
end
end
def validator_for_name(schema_name, raise_not_found=true)
return default_validator unless schema_name
schema_name = schema_name.to_s
validator = validators.values.detect do |v|
Array(v.names).include?(schema_name)
end
if validator.nil? && raise_not_found
raise JSON::Schema::SchemaError.new("The requested JSON schema version is not supported")
else
validator
end
end
def validator_for(schema_uri)
warn "[DEPRECATION NOTICE] JSON::Validator#validator_for has been replaced by JSON::Validator#validator_for_uri and will be removed in version >= 3. Please use the #validator_for_uri method instead."
validator_for_uri(schema_uri)
end
def register_validator(v)
@@validators["#{v.uri.scheme}://#{v.uri.host}#{v.uri.path}"] = v
end
def register_default_validator(v)
@@default_validator = v
end
def register_format_validator(format, validation_proc, versions = (@@validators.flat_map{ |k, v| v.names.first } + [nil]))
custom_format_validator = JSON::Schema::CustomFormat.new(validation_proc)
versions.each do |version|
validator = validator_for_name(version)
validator.formats[format.to_s] = custom_format_validator
end
end
def deregister_format_validator(format, versions = (@@validators.flat_map{ |k, v| v.names.first } + [nil]))
versions.each do |version|
validator = validator_for_name(version)
validator.formats[format.to_s] = validator.default_formats[format.to_s]
end
end
def restore_default_formats(versions = (@@validators.flat_map{ |k, v| v.names.first } + [nil]))
versions.each do |version|
validator = validator_for_name(version)
validator.formats = validator.default_formats.clone
end
end
def json_backend
if defined?(MultiJson)
MultiJson.respond_to?(:adapter) ? MultiJson.adapter : MultiJson.engine
else
@@json_backend
end
end
def json_backend=(backend)
if defined?(MultiJson)
backend = backend == 'json' ? 'json_gem' : backend
MultiJson.respond_to?(:use) ? MultiJson.use(backend) : MultiJson.engine = backend
else
backend = backend.to_s
if @@available_json_backends.include?(backend)
@@json_backend = backend
else
raise JSON::Schema::JsonParseError.new("The JSON backend '#{backend}' could not be found.")
end
end
end
def parse(s)
if defined?(MultiJson)
begin
MultiJson.respond_to?(:adapter) ? MultiJson.load(s) : MultiJson.decode(s)
rescue MultiJson::ParseError => e
raise JSON::Schema::JsonParseError.new(e.message)
end
else
case @@json_backend.to_s
when 'json'
begin
JSON.parse(s, :quirks_mode => true)
rescue JSON::ParserError => e
raise JSON::Schema::JsonParseError.new(e.message)
end
when 'yajl'
begin
json = StringIO.new(s)
parser = Yajl::Parser.new
parser.parse(json) or raise JSON::Schema::JsonParseError.new("The JSON could not be parsed by yajl")
rescue Yajl::ParseError => e
raise JSON::Schema::JsonParseError.new(e.message)
end
else
raise JSON::Schema::JsonParseError.new("No supported JSON parsers found. The following parsers are suported:\n * yajl-ruby\n * json")
end
end
end
def merge_missing_values(source, destination)
case destination
when Hash
source.each do |key, source_value|
destination_value = destination[key] || destination[key.to_sym]
if destination_value.nil?
destination[key] = source_value
else
merge_missing_values(source_value, destination_value)
end
end
when Array
source.each_with_index do |source_value, i|
destination_value = destination[i]
merge_missing_values(source_value, destination_value)
end
end
end
if !defined?(MultiJson)
if Gem::Specification::find_all_by_name('json').any?
require 'json'
@@available_json_backends << 'json'
@@json_backend = 'json'
else
# Try force-loading json for rubies > 1.9.2
begin
require 'json'
@@available_json_backends << 'json'
@@json_backend = 'json'
rescue LoadError
end
end
if Gem::Specification::find_all_by_name('yajl-ruby').any?
require 'yajl'
@@available_json_backends << 'yajl'
@@json_backend = 'yajl'
end
if @@json_backend == 'yajl'
@@serializer = lambda{|o| Yajl::Encoder.encode(o) }
elsif @@json_backend == 'json'
@@serializer = lambda{|o| JSON.dump(o) }
else
@@serializer = lambda{|o| YAML.dump(o) }
end
end
end
private
if Gem::Specification::find_all_by_name('uuidtools').any?
require 'uuidtools'
@@fake_uuid_generator = lambda{|s| UUIDTools::UUID.sha1_create(UUIDTools::UUID_URL_NAMESPACE, s).to_s }
else
require 'json-schema/util/uuid'
@@fake_uuid_generator = lambda{|s| JSON::Util::UUID.create_v5(s,JSON::Util::UUID::Nil).to_s }
end
def serialize schema
if defined?(MultiJson)
MultiJson.respond_to?(:dump) ? MultiJson.dump(schema) : MultiJson.encode(schema)
else
@@serializer.call(schema)
end
end
def fake_uuid schema
@@fake_uuid_generator.call(schema)
end
def initialize_schema(schema)
if schema.is_a?(String)
begin
# Build a fake URI for this
schema_uri = JSON::Util::URI.parse(fake_uuid(schema))
schema = JSON::Schema.new(self.class.parse(schema), schema_uri, @options[:version])
if @options[:list] && @options[:fragment].nil?
schema = schema.to_array_schema
end
self.class.add_schema(schema)
rescue JSON::Schema::JsonParseError
# Build a uri for it
schema_uri = Util::URI.normalized_uri(schema)
if !self.class.schema_loaded?(schema_uri)
schema = @options[:schema_reader].read(schema_uri)
schema = JSON::Schema.stringify(schema)
if @options[:list] && @options[:fragment].nil?
schema = schema.to_array_schema
end
self.class.add_schema(schema)
else
schema = self.class.schema_for_uri(schema_uri)
if @options[:list] && @options[:fragment].nil?
schema = schema.to_array_schema
schema.uri = JSON::Util::URI.parse(fake_uuid(serialize(schema.schema)))
self.class.add_schema(schema)
end
schema
end
end
elsif schema.is_a?(Hash)
schema_uri = JSON::Util::URI.parse(fake_uuid(serialize(schema)))
schema = JSON::Schema.stringify(schema)
schema = JSON::Schema.new(schema, schema_uri, @options[:version])
if @options[:list] && @options[:fragment].nil?
schema = schema.to_array_schema
end
self.class.add_schema(schema)
else
raise JSON::Schema::SchemaParseError, "Invalid schema - must be either a string or a hash"
end
schema
end
def initialize_data(data)
if @options[:parse_data]
if @options[:json]
data = self.class.parse(data)
elsif @options[:uri]
json_uri = Util::URI.normalized_uri(data)
data = self.class.parse(custom_open(json_uri))
elsif data.is_a?(String)
begin
data = self.class.parse(data)
rescue JSON::Schema::JsonParseError
begin
json_uri = Util::URI.normalized_uri(data)
data = self.class.parse(custom_open(json_uri))
rescue JSON::Schema::JsonLoadError, JSON::Schema::UriError
# Silently discard the error - use the data as-is
end
end
end
end
JSON::Schema.stringify(data)
end
def custom_open(uri)
uri = Util::URI.normalized_uri(uri) if uri.is_a?(String)
if uri.absolute? && Util::URI::SUPPORTED_PROTOCOLS.include?(uri.scheme)
begin
open(uri.to_s).read
rescue OpenURI::HTTPError, Timeout::Error => e
raise JSON::Schema::JsonLoadError, e.message
end
else
begin
File.read(JSON::Util::URI.unescaped_path(uri))
rescue SystemCallError => e
raise JSON::Schema::JsonLoadError, e.message
end
end
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/validators/ 0000775 0000000 0000000 00000000000 13411675645 0022051 5 ustar 00root root 0000000 0000000 ruby-json-schema-2.8.1/lib/json-schema/validators/draft1.rb 0000664 0000000 0000000 00000003124 13411675645 0023557 0 ustar 00root root 0000000 0000000 require 'json-schema/schema/validator'
module JSON
class Schema
class Draft1 < Validator
def initialize
super
@attributes = {
"type" => JSON::Schema::TypeAttribute,
"disallow" => JSON::Schema::DisallowAttribute,
"format" => JSON::Schema::FormatAttribute,
"maximum" => JSON::Schema::MaximumInclusiveAttribute,
"minimum" => JSON::Schema::MinimumInclusiveAttribute,
"minItems" => JSON::Schema::MinItemsAttribute,
"maxItems" => JSON::Schema::MaxItemsAttribute,
"minLength" => JSON::Schema::MinLengthAttribute,
"maxLength" => JSON::Schema::MaxLengthAttribute,
"maxDecimal" => JSON::Schema::MaxDecimalAttribute,
"enum" => JSON::Schema::EnumAttribute,
"properties" => JSON::Schema::PropertiesOptionalAttribute,
"pattern" => JSON::Schema::PatternAttribute,
"additionalProperties" => JSON::Schema::AdditionalPropertiesAttribute,
"items" => JSON::Schema::ItemsAttribute,
"extends" => JSON::Schema::ExtendsAttribute
}
@default_formats = {
'date-time' => DateTimeFormat,
'date' => DateFormat,
'time' => TimeFormat,
'ip-address' => IP4Format,
'ipv6' => IP6Format,
'uri' => UriFormat
}
@formats = @default_formats.clone
@uri = JSON::Util::URI.parse("http://json-schema.org/draft-01/schema#")
@names = ["draft1"]
@metaschema_name = "draft-01.json"
end
JSON::Validator.register_validator(self.new)
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/validators/draft2.rb 0000664 0000000 0000000 00000003225 13411675645 0023562 0 ustar 00root root 0000000 0000000 require 'json-schema/schema/validator'
module JSON
class Schema
class Draft2 < Validator
def initialize
super
@attributes = {
"type" => JSON::Schema::TypeAttribute,
"disallow" => JSON::Schema::DisallowAttribute,
"format" => JSON::Schema::FormatAttribute,
"maximum" => JSON::Schema::MaximumInclusiveAttribute,
"minimum" => JSON::Schema::MinimumInclusiveAttribute,
"minItems" => JSON::Schema::MinItemsAttribute,
"maxItems" => JSON::Schema::MaxItemsAttribute,
"uniqueItems" => JSON::Schema::UniqueItemsAttribute,
"minLength" => JSON::Schema::MinLengthAttribute,
"maxLength" => JSON::Schema::MaxLengthAttribute,
"divisibleBy" => JSON::Schema::DivisibleByAttribute,
"enum" => JSON::Schema::EnumAttribute,
"properties" => JSON::Schema::PropertiesOptionalAttribute,
"pattern" => JSON::Schema::PatternAttribute,
"additionalProperties" => JSON::Schema::AdditionalPropertiesAttribute,
"items" => JSON::Schema::ItemsAttribute,
"extends" => JSON::Schema::ExtendsAttribute
}
@default_formats = {
'date-time' => DateTimeFormat,
'date' => DateFormat,
'time' => TimeFormat,
'ip-address' => IP4Format,
'ipv6' => IP6Format,
'uri' => UriFormat
}
@formats = @default_formats.clone
@uri = JSON::Util::URI.parse("http://json-schema.org/draft-02/schema#")
@names = ["draft2"]
@metaschema_name = "draft-02.json"
end
JSON::Validator.register_validator(self.new)
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/validators/draft3.rb 0000664 0000000 0000000 00000003651 13411675645 0023566 0 ustar 00root root 0000000 0000000 require 'json-schema/schema/validator'
module JSON
class Schema
class Draft3 < Validator
def initialize
super
@attributes = {
"type" => JSON::Schema::TypeAttribute,
"disallow" => JSON::Schema::DisallowAttribute,
"format" => JSON::Schema::FormatAttribute,
"maximum" => JSON::Schema::MaximumAttribute,
"minimum" => JSON::Schema::MinimumAttribute,
"minItems" => JSON::Schema::MinItemsAttribute,
"maxItems" => JSON::Schema::MaxItemsAttribute,
"uniqueItems" => JSON::Schema::UniqueItemsAttribute,
"minLength" => JSON::Schema::MinLengthAttribute,
"maxLength" => JSON::Schema::MaxLengthAttribute,
"divisibleBy" => JSON::Schema::DivisibleByAttribute,
"enum" => JSON::Schema::EnumAttribute,
"properties" => JSON::Schema::PropertiesAttribute,
"pattern" => JSON::Schema::PatternAttribute,
"patternProperties" => JSON::Schema::PatternPropertiesAttribute,
"additionalProperties" => JSON::Schema::AdditionalPropertiesAttribute,
"items" => JSON::Schema::ItemsAttribute,
"additionalItems" => JSON::Schema::AdditionalItemsAttribute,
"dependencies" => JSON::Schema::DependenciesAttribute,
"extends" => JSON::Schema::ExtendsAttribute,
"$ref" => JSON::Schema::RefAttribute
}
@default_formats = {
'date-time' => DateTimeFormat,
'date' => DateFormat,
'ip-address' => IP4Format,
'ipv6' => IP6Format,
'time' => TimeFormat,
'uri' => UriFormat
}
@formats = @default_formats.clone
@uri = JSON::Util::URI.parse("http://json-schema.org/draft-03/schema#")
@names = ["draft3", "http://json-schema.org/draft-03/schema#"]
@metaschema_name = "draft-03.json"
end
JSON::Validator.register_validator(self.new)
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/validators/draft4.rb 0000664 0000000 0000000 00000004453 13411675645 0023570 0 ustar 00root root 0000000 0000000 require 'json-schema/schema/validator'
module JSON
class Schema
class Draft4 < Validator
def initialize
super
@attributes = {
"type" => JSON::Schema::TypeV4Attribute,
"allOf" => JSON::Schema::AllOfAttribute,
"anyOf" => JSON::Schema::AnyOfAttribute,
"oneOf" => JSON::Schema::OneOfAttribute,
"not" => JSON::Schema::NotAttribute,
"disallow" => JSON::Schema::DisallowAttribute,
"format" => JSON::Schema::FormatAttribute,
"maximum" => JSON::Schema::MaximumAttribute,
"minimum" => JSON::Schema::MinimumAttribute,
"minItems" => JSON::Schema::MinItemsAttribute,
"maxItems" => JSON::Schema::MaxItemsAttribute,
"minProperties" => JSON::Schema::MinPropertiesAttribute,
"maxProperties" => JSON::Schema::MaxPropertiesAttribute,
"uniqueItems" => JSON::Schema::UniqueItemsAttribute,
"minLength" => JSON::Schema::MinLengthAttribute,
"maxLength" => JSON::Schema::MaxLengthAttribute,
"multipleOf" => JSON::Schema::MultipleOfAttribute,
"enum" => JSON::Schema::EnumAttribute,
"properties" => JSON::Schema::PropertiesV4Attribute,
"required" => JSON::Schema::RequiredAttribute,
"pattern" => JSON::Schema::PatternAttribute,
"patternProperties" => JSON::Schema::PatternPropertiesAttribute,
"additionalProperties" => JSON::Schema::AdditionalPropertiesAttribute,
"items" => JSON::Schema::ItemsAttribute,
"additionalItems" => JSON::Schema::AdditionalItemsAttribute,
"dependencies" => JSON::Schema::DependenciesV4Attribute,
"extends" => JSON::Schema::ExtendsAttribute,
"$ref" => JSON::Schema::RefAttribute
}
@default_formats = {
'date-time' => DateTimeV4Format,
'ipv4' => IP4Format,
'ipv6' => IP6Format,
'uri' => UriFormat
}
@formats = @default_formats.clone
@uri = JSON::Util::URI.parse("http://json-schema.org/draft-04/schema#")
@names = ["draft4", "http://json-schema.org/draft-04/schema#"]
@metaschema_name = "draft-04.json"
end
JSON::Validator.register_validator(self.new)
JSON::Validator.register_default_validator(self.new)
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/validators/draft6.rb 0000664 0000000 0000000 00000004445 13411675645 0023573 0 ustar 00root root 0000000 0000000 require 'json-schema/schema/validator'
module JSON
class Schema
class Draft6 < Validator
def initialize
super
@attributes = {
"type" => JSON::Schema::TypeV4Attribute,
"allOf" => JSON::Schema::AllOfAttribute,
"anyOf" => JSON::Schema::AnyOfAttribute,
"oneOf" => JSON::Schema::OneOfAttribute,
"not" => JSON::Schema::NotAttribute,
"disallow" => JSON::Schema::DisallowAttribute,
"format" => JSON::Schema::FormatAttribute,
"maximum" => JSON::Schema::MaximumAttribute,
"minimum" => JSON::Schema::MinimumAttribute,
"minItems" => JSON::Schema::MinItemsAttribute,
"maxItems" => JSON::Schema::MaxItemsAttribute,
"minProperties" => JSON::Schema::MinPropertiesAttribute,
"maxProperties" => JSON::Schema::MaxPropertiesAttribute,
"uniqueItems" => JSON::Schema::UniqueItemsAttribute,
"minLength" => JSON::Schema::MinLengthAttribute,
"maxLength" => JSON::Schema::MaxLengthAttribute,
"multipleOf" => JSON::Schema::MultipleOfAttribute,
"enum" => JSON::Schema::EnumAttribute,
"properties" => JSON::Schema::PropertiesV4Attribute,
"required" => JSON::Schema::RequiredAttribute,
"pattern" => JSON::Schema::PatternAttribute,
"patternProperties" => JSON::Schema::PatternPropertiesAttribute,
"additionalProperties" => JSON::Schema::AdditionalPropertiesAttribute,
"items" => JSON::Schema::ItemsAttribute,
"additionalItems" => JSON::Schema::AdditionalItemsAttribute,
"dependencies" => JSON::Schema::DependenciesV4Attribute,
"extends" => JSON::Schema::ExtendsAttribute,
"$ref" => JSON::Schema::RefAttribute
}
@default_formats = {
'date-time' => DateTimeV4Format,
'ipv4' => IP4Format,
'ipv6' => IP6Format,
'uri' => UriFormat
}
@formats = @default_formats.clone
@uri = JSON::Util::URI.parse("http://json-schema.org/draft/schema#")
@names = ["draft6", "http://json-schema.org/draft/schema#"]
@metaschema_name = "draft-06.json"
end
JSON::Validator.register_validator(self.new)
JSON::Validator.register_default_validator(self.new)
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/validators/hyper-draft1.rb 0000664 0000000 0000000 00000000404 13411675645 0024702 0 ustar 00root root 0000000 0000000 module JSON
class Schema
class HyperDraft1 < Draft1
def initialize
super
@uri = JSON::Util::URI.parse("http://json-schema.org/draft-01/hyper-schema#")
end
JSON::Validator.register_validator(self.new)
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/validators/hyper-draft2.rb 0000664 0000000 0000000 00000000404 13411675645 0024703 0 ustar 00root root 0000000 0000000 module JSON
class Schema
class HyperDraft2 < Draft2
def initialize
super
@uri = JSON::Util::URI.parse("http://json-schema.org/draft-02/hyper-schema#")
end
JSON::Validator.register_validator(self.new)
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/validators/hyper-draft3.rb 0000664 0000000 0000000 00000000404 13411675645 0024704 0 ustar 00root root 0000000 0000000 module JSON
class Schema
class HyperDraft3 < Draft3
def initialize
super
@uri = JSON::Util::URI.parse("http://json-schema.org/draft-03/hyper-schema#")
end
JSON::Validator.register_validator(self.new)
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/validators/hyper-draft4.rb 0000664 0000000 0000000 00000000404 13411675645 0024705 0 ustar 00root root 0000000 0000000 module JSON
class Schema
class HyperDraft4 < Draft4
def initialize
super
@uri = JSON::Util::URI.parse("http://json-schema.org/draft-04/hyper-schema#")
end
JSON::Validator.register_validator(self.new)
end
end
end
ruby-json-schema-2.8.1/lib/json-schema/validators/hyper-draft6.rb 0000664 0000000 0000000 00000000404 13411675645 0024707 0 ustar 00root root 0000000 0000000 module JSON
class Schema
class HyperDraft6 < Draft6
def initialize
super
@uri = JSON::Util::URI.parse("http://json-schema.org/draft-06/hyper-schema#")
end
JSON::Validator.register_validator(self.new)
end
end
end
ruby-json-schema-2.8.1/resources/ 0000775 0000000 0000000 00000000000 13411675645 0016736 5 ustar 00root root 0000000 0000000 ruby-json-schema-2.8.1/resources/draft-01.json 0000664 0000000 0000000 00000004713 13411675645 0021154 0 ustar 00root root 0000000 0000000 {
"$schema" : "http://json-schema.org/draft-01/hyper-schema#",
"id" : "http://json-schema.org/draft-01/schema#",
"type" : "object",
"properties" : {
"type" : {
"type" : ["string", "array"],
"items" : {
"type" : ["string", {"$ref" : "#"}]
},
"optional" : true,
"default" : "any"
},
"properties" : {
"type" : "object",
"additionalProperties" : {"$ref" : "#"},
"optional" : true,
"default" : {}
},
"items" : {
"type" : [{"$ref" : "#"}, "array"],
"items" : {"$ref" : "#"},
"optional" : true,
"default" : {}
},
"optional" : {
"type" : "boolean",
"optional" : true,
"default" : false
},
"additionalProperties" : {
"type" : [{"$ref" : "#"}, "boolean"],
"optional" : true,
"default" : {}
},
"requires" : {
"type" : ["string", {"$ref" : "#"}],
"optional" : true
},
"minimum" : {
"type" : "number",
"optional" : true
},
"maximum" : {
"type" : "number",
"optional" : true
},
"minimumCanEqual" : {
"type" : "boolean",
"optional" : true,
"requires" : "minimum",
"default" : true
},
"maximumCanEqual" : {
"type" : "boolean",
"optional" : true,
"requires" : "maximum",
"default" : true
},
"minItems" : {
"type" : "integer",
"optional" : true,
"minimum" : 0,
"default" : 0
},
"maxItems" : {
"type" : "integer",
"optional" : true,
"minimum" : 0
},
"pattern" : {
"type" : "string",
"optional" : true,
"format" : "regex"
},
"minLength" : {
"type" : "integer",
"optional" : true,
"minimum" : 0,
"default" : 0
},
"maxLength" : {
"type" : "integer",
"optional" : true
},
"enum" : {
"type" : "array",
"optional" : true,
"minItems" : 1
},
"title" : {
"type" : "string",
"optional" : true
},
"description" : {
"type" : "string",
"optional" : true
},
"format" : {
"type" : "string",
"optional" : true
},
"contentEncoding" : {
"type" : "string",
"optional" : true
},
"default" : {
"type" : "any",
"optional" : true
},
"maxDecimal" : {
"type" : "integer",
"optional" : true,
"minimum" : 0
},
"disallow" : {
"type" : ["string", "array"],
"items" : {"type" : "string"},
"optional" : true
},
"extends" : {
"type" : [{"$ref" : "#"}, "array"],
"items" : {"$ref" : "#"},
"optional" : true,
"default" : {}
}
},
"optional" : true,
"default" : {}
} ruby-json-schema-2.8.1/resources/draft-02.json 0000664 0000000 0000000 00000005244 13411675645 0021155 0 ustar 00root root 0000000 0000000 {
"$schema" : "http://json-schema.org/draft-02/hyper-schema#",
"id" : "http://json-schema.org/draft-02/schema#",
"type" : "object",
"properties" : {
"type" : {
"type" : ["string", "array"],
"items" : {
"type" : ["string", {"$ref" : "#"}]
},
"optional" : true,
"uniqueItems" : true,
"default" : "any"
},
"properties" : {
"type" : "object",
"additionalProperties" : {"$ref" : "#"},
"optional" : true,
"default" : {}
},
"items" : {
"type" : [{"$ref" : "#"}, "array"],
"items" : {"$ref" : "#"},
"optional" : true,
"default" : {}
},
"optional" : {
"type" : "boolean",
"optional" : true,
"default" : false
},
"additionalProperties" : {
"type" : [{"$ref" : "#"}, "boolean"],
"optional" : true,
"default" : {}
},
"requires" : {
"type" : ["string", {"$ref" : "#"}],
"optional" : true
},
"minimum" : {
"type" : "number",
"optional" : true
},
"maximum" : {
"type" : "number",
"optional" : true
},
"minimumCanEqual" : {
"type" : "boolean",
"optional" : true,
"requires" : "minimum",
"default" : true
},
"maximumCanEqual" : {
"type" : "boolean",
"optional" : true,
"requires" : "maximum",
"default" : true
},
"minItems" : {
"type" : "integer",
"optional" : true,
"minimum" : 0,
"default" : 0
},
"maxItems" : {
"type" : "integer",
"optional" : true,
"minimum" : 0
},
"uniqueItems" : {
"type" : "boolean",
"optional" : true,
"default" : false
},
"pattern" : {
"type" : "string",
"optional" : true,
"format" : "regex"
},
"minLength" : {
"type" : "integer",
"optional" : true,
"minimum" : 0,
"default" : 0
},
"maxLength" : {
"type" : "integer",
"optional" : true
},
"enum" : {
"type" : "array",
"optional" : true,
"minItems" : 1,
"uniqueItems" : true
},
"title" : {
"type" : "string",
"optional" : true
},
"description" : {
"type" : "string",
"optional" : true
},
"format" : {
"type" : "string",
"optional" : true
},
"contentEncoding" : {
"type" : "string",
"optional" : true
},
"default" : {
"type" : "any",
"optional" : true
},
"divisibleBy" : {
"type" : "number",
"minimum" : 0,
"minimumCanEqual" : false,
"optional" : true,
"default" : 1
},
"disallow" : {
"type" : ["string", "array"],
"items" : {"type" : "string"},
"optional" : true,
"uniqueItems" : true
},
"extends" : {
"type" : [{"$ref" : "#"}, "array"],
"items" : {"$ref" : "#"},
"optional" : true,
"default" : {}
}
},
"optional" : true,
"default" : {}
} ruby-json-schema-2.8.1/resources/draft-03.json 0000664 0000000 0000000 00000007427 13411675645 0021163 0 ustar 00root root 0000000 0000000 {
"$schema": "http://json-schema.org/draft-03/schema#",
"id": "http://json-schema.org/draft-03/schema#",
"type": "object",
"properties": {
"type": {
"type": [ "string", "array" ],
"items": {
"type": [ "string", { "$ref": "#" } ]
},
"uniqueItems": true,
"default": "any"
},
"properties": {
"type": "object",
"additionalProperties": { "$ref": "#" },
"default": {}
},
"patternProperties": {
"type": "object",
"additionalProperties": { "$ref": "#" },
"default": {}
},
"additionalProperties": {
"type": [ { "$ref": "#" }, "boolean" ],
"default": {}
},
"items": {
"type": [ { "$ref": "#" }, "array" ],
"items": { "$ref": "#" },
"default": {}
},
"additionalItems": {
"type": [ { "$ref": "#" }, "boolean" ],
"default": {}
},
"required": {
"type": "boolean",
"default": false
},
"dependencies": {
"type": "object",
"additionalProperties": {
"type": [ "string", "array", { "$ref": "#" } ],
"items": {
"type": "string"
}
},
"default": {}
},
"minimum": {
"type": "number"
},
"maximum": {
"type": "number"
},
"exclusiveMinimum": {
"type": "boolean",
"default": false
},
"exclusiveMaximum": {
"type": "boolean",
"default": false
},
"minItems": {
"type": "integer",
"minimum": 0,
"default": 0
},
"maxItems": {
"type": "integer",
"minimum": 0
},
"uniqueItems": {
"type": "boolean",
"default": false
},
"pattern": {
"type": "string",
"format": "regex"
},
"minLength": {
"type": "integer",
"minimum": 0,
"default": 0
},
"maxLength": {
"type": "integer"
},
"enum": {
"type": "array",
"minItems": 1,
"uniqueItems": true
},
"default": {
"type": "any"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"format": {
"type": "string"
},
"divisibleBy": {
"type": "number",
"minimum": 0,
"exclusiveMinimum": true,
"default": 1
},
"disallow": {
"type": [ "string", "array" ],
"items": {
"type": [ "string", { "$ref": "#" } ]
},
"uniqueItems": true
},
"extends": {
"type": [ { "$ref": "#" }, "array" ],
"items": { "$ref": "#" },
"default": {}
},
"id": {
"type": "string",
"format": "uri"
},
"$ref": {
"type": "string",
"format": "uri"
},
"$schema": {
"type": "string",
"format": "uri"
}
},
"dependencies": {
"exclusiveMinimum": "minimum",
"exclusiveMaximum": "maximum"
},
"default": {}
}
ruby-json-schema-2.8.1/resources/draft-04.json 0000664 0000000 0000000 00000010427 13411675645 0021156 0 ustar 00root root 0000000 0000000 {
"id": "http://json-schema.org/draft-04/schema#",
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Core schema meta-schema",
"definitions": {
"schemaArray": {
"type": "array",
"minItems": 1,
"items": { "$ref": "#" }
},
"positiveInteger": {
"type": "integer",
"minimum": 0
},
"positiveIntegerDefault0": {
"allOf": [ { "$ref": "#/definitions/positiveInteger" }, { "default": 0 } ]
},
"simpleTypes": {
"enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ]
},
"stringArray": {
"type": "array",
"items": { "type": "string" },
"minItems": 1,
"uniqueItems": true
}
},
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uri"
},
"$schema": {
"type": "string",
"format": "uri"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"default": {},
"multipleOf": {
"type": "number",
"minimum": 0,
"exclusiveMinimum": true
},
"maximum": {
"type": "number"
},
"exclusiveMaximum": {
"type": "boolean",
"default": false
},
"minimum": {
"type": "number"
},
"exclusiveMinimum": {
"type": "boolean",
"default": false
},
"maxLength": { "$ref": "#/definitions/positiveInteger" },
"minLength": { "$ref": "#/definitions/positiveIntegerDefault0" },
"pattern": {
"type": "string",
"format": "regex"
},
"additionalItems": {
"anyOf": [
{ "type": "boolean" },
{ "$ref": "#" }
],
"default": {}
},
"items": {
"anyOf": [
{ "$ref": "#" },
{ "$ref": "#/definitions/schemaArray" }
],
"default": {}
},
"maxItems": { "$ref": "#/definitions/positiveInteger" },
"minItems": { "$ref": "#/definitions/positiveIntegerDefault0" },
"uniqueItems": {
"type": "boolean",
"default": false
},
"maxProperties": { "$ref": "#/definitions/positiveInteger" },
"minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" },
"required": { "$ref": "#/definitions/stringArray" },
"additionalProperties": {
"anyOf": [
{ "type": "boolean" },
{ "$ref": "#" }
],
"default": {}
},
"definitions": {
"type": "object",
"additionalProperties": { "$ref": "#" },
"default": {}
},
"properties": {
"type": "object",
"additionalProperties": { "$ref": "#" },
"default": {}
},
"patternProperties": {
"type": "object",
"additionalProperties": { "$ref": "#" },
"default": {}
},
"dependencies": {
"type": "object",
"additionalProperties": {
"anyOf": [
{ "$ref": "#" },
{ "$ref": "#/definitions/stringArray" }
]
}
},
"enum": {
"type": "array",
"minItems": 1,
"uniqueItems": true
},
"type": {
"anyOf": [
{ "$ref": "#/definitions/simpleTypes" },
{
"type": "array",
"items": { "$ref": "#/definitions/simpleTypes" },
"minItems": 1,
"uniqueItems": true
}
]
},
"allOf": { "$ref": "#/definitions/schemaArray" },
"anyOf": { "$ref": "#/definitions/schemaArray" },
"oneOf": { "$ref": "#/definitions/schemaArray" },
"not": { "$ref": "#" }
},
"dependencies": {
"exclusiveMaximum": [ "maximum" ],
"exclusiveMinimum": [ "minimum" ]
},
"default": {}
}
ruby-json-schema-2.8.1/resources/draft-06.json 0000664 0000000 0000000 00000010353 13411675645 0021156 0 ustar 00root root 0000000 0000000 {
"$schema": "http://json-schema.org/draft/schema#",
"$id": "http://json-schema.org/draft/schema#",
"title": "Core schema meta-schema",
"definitions": {
"schemaArray": {
"type": "array",
"minItems": 1,
"items": { "$ref": "#" }
},
"positiveInteger": {
"type": "integer",
"minimum": 0
},
"positiveIntegerDefault0": {
"allOf": [
{ "$ref": "#/definitions/positiveInteger" },
{ "default": 0 }
]
},
"simpleTypes": {
"enum": [
"array",
"boolean",
"integer",
"null",
"number",
"object",
"string"
]
},
"stringArray": {
"type": "array",
"items": { "type": "string" },
"uniqueItems": true,
"defaultItems": []
}
},
"type": ["object", "boolean"],
"properties": {
"$id": {
"type": "string",
"format": "uri-reference"
},
"$schema": {
"type": "string",
"format": "uri"
},
"$ref": {
"type": "string",
"format": "uri-reference"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"default": {},
"multipleOf": {
"type": "number",
"exclusiveMinimum": 0
},
"maximum": {
"type": "number"
},
"exclusiveMaximum": {
"type": "number"
},
"minimum": {
"type": "number"
},
"exclusiveMinimum": {
"type": "number"
},
"maxLength": { "$ref": "#/definitions/positiveInteger" },
"minLength": { "$ref": "#/definitions/positiveIntegerDefault0" },
"pattern": {
"type": "string",
"format": "regex"
},
"additionalItems": { "$ref": "#" },
"items": {
"anyOf": [
{ "$ref": "#" },
{ "$ref": "#/definitions/schemaArray" }
],
"default": {}
},
"maxItems": { "$ref": "#/definitions/positiveInteger" },
"minItems": { "$ref": "#/definitions/positiveIntegerDefault0" },
"uniqueItems": {
"type": "boolean",
"default": false
},
"contains": { "$ref": "#" },
"maxProperties": { "$ref": "#/definitions/positiveInteger" },
"minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" },
"required": { "$ref": "#/definitions/stringArray" },
"additionalProperties": { "$ref": "#" },
"definitions": {
"type": "object",
"additionalProperties": { "$ref": "#" },
"default": {}
},
"properties": {
"type": "object",
"additionalProperties": { "$ref": "#" },
"default": {}
},
"patternProperties": {
"type": "object",
"additionalProperties": { "$ref": "#" },
"default": {}
},
"dependencies": {
"type": "object",
"additionalProperties": {
"anyOf": [
{ "$ref": "#" },
{ "$ref": "#/definitions/stringArray" }
]
}
},
"propertyNames": { "$ref": "#" },
"const": {},
"enum": {
"type": "array",
"minItems": 1,
"uniqueItems": true
},
"type": {
"anyOf": [
{ "$ref": "#/definitions/simpleTypes" },
{
"type": "array",
"items": { "$ref": "#/definitions/simpleTypes" },
"minItems": 1,
"uniqueItems": true
}
]
},
"format": { "type": "string" },
"allOf": { "$ref": "#/definitions/schemaArray" },
"anyOf": { "$ref": "#/definitions/schemaArray" },
"oneOf": { "$ref": "#/definitions/schemaArray" },
"not": { "$ref": "#" }
},
"default": {}
}
ruby-json-schema-2.8.1/test/ 0000775 0000000 0000000 00000000000 13411675645 0015703 5 ustar 00root root 0000000 0000000 ruby-json-schema-2.8.1/test/all_of_ref_schema_test.rb 0000664 0000000 0000000 00000002245 13411675645 0022702 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class AllOfRefSchemaTest < Minitest::Test
def schema
schema_fixture_path('all_of_ref_schema.json')
end
def data
data_fixture_path('all_of_ref_data.json')
end
def test_all_of_ref_schema_fails
refute_valid schema, data
end
def test_all_of_ref_schema_succeeds
assert_valid schema, %({"name": 42})
end
def test_all_of_ref_subschema_errors
errors = JSON::Validator.fully_validate(schema, data, :errors_as_objects => true)
nested_errors = errors[0][:errors]
assert_equal([:allof_0], nested_errors.keys, 'should have nested errors for each allOf subschema')
assert_match(/the property '#\/name' of type string did not match the following type: integer/i, nested_errors[:allof_0][0][:message])
end
def test_all_of_ref_message
errors = JSON::Validator.fully_validate(schema, data)
expected_message = """The property '#/' of type object did not match all of the required schemas. The schema specific errors were:
- allOf #0:
- The property '#/name' of type string did not match the following type: integer"""
assert_equal(expected_message, errors[0])
end
end
ruby-json-schema-2.8.1/test/any_of_ref_schema_test.rb 0000664 0000000 0000000 00000003074 13411675645 0022722 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class AnyOfRefSchemaTest < Minitest::Test
def schema
schema_fixture_path('any_of_ref_schema.json')
end
def test_any_of_ref_schema
assert_valid schema, data_fixture_path('any_of_ref_data.json')
end
def test_any_of_ref_subschema_errors
data = %({"names": ["jack"]})
errors = JSON::Validator.fully_validate(schema, data, :errors_as_objects => true)
nested_errors = errors[0][:errors]
assert_equal([:anyof_0, :anyof_1, :anyof_2], nested_errors.keys, 'should have nested errors for each anyOf subschema')
assert_match(/the property '#\/names\/0' value "jack" did not match the regex 'john'/i, nested_errors[:anyof_0][0][:message])
assert_match(/the property '#\/names\/0' value "jack" did not match the regex 'jane'/i, nested_errors[:anyof_1][0][:message])
assert_match(/the property '#\/names\/0' value "jack" did not match the regex 'jimmy'/i, nested_errors[:anyof_2][0][:message])
end
def test_any_of_ref_message
data = %({"names": ["jack"]})
errors = JSON::Validator.fully_validate(schema, data)
expected_message = """The property '#/names/0' of type string did not match one or more of the required schemas. The schema specific errors were:
- anyOf #0:
- The property '#/names/0' value \"jack\" did not match the regex 'john'
- anyOf #1:
- The property '#/names/0' value \"jack\" did not match the regex 'jane'
- anyOf #2:
- The property '#/names/0' value \"jack\" did not match the regex 'jimmy'"""
assert_equal(expected_message, errors[0])
end
end
ruby-json-schema-2.8.1/test/bad_schema_ref_test.rb 0000664 0000000 0000000 00000002562 13411675645 0022176 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
require 'socket'
class BadSchemaRefTest < Minitest::Test
def setup
WebMock.allow_net_connect!
end
def teardown
WebMock.disable_net_connect!
end
def test_bad_uri_ref
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"type" => "array",
"items" => { "$ref" => "../google.json"}
}
data = [1,2,3]
error = assert_raises(JSON::Schema::ReadFailed) do
JSON::Validator.validate(schema,data)
end
expanded_path = File.expand_path("../../google.json", __FILE__)
assert_equal(:file, error.type)
assert_equal(expanded_path, error.location)
assert_equal("Read of file at #{expanded_path} failed", error.message)
end
def test_bad_host_ref
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"type" => "array",
"items" => { "$ref" => "http://ppcheesecheseunicornnuuuurrrrr.example.invalid/json.schema"}
}
data = [1,2,3]
error = assert_raises(JSON::Schema::ReadFailed) do
JSON::Validator.validate(schema,data)
end
assert_equal(:uri, error.type)
assert_equal("http://ppcheesecheseunicornnuuuurrrrr.example.invalid/json.schema", error.location)
assert_equal("Read of URI at http://ppcheesecheseunicornnuuuurrrrr.example.invalid/json.schema failed", error.message)
end
end
ruby-json-schema-2.8.1/test/caching_test.rb 0000664 0000000 0000000 00000002223 13411675645 0020662 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class CachingTestTest < Minitest::Test
def setup
@schema = Tempfile.new(['schema', '.json'])
end
def teardown
@schema.close
@schema.unlink
JSON::Validator.clear_cache
end
def test_caching
set_schema('type' => 'string')
assert_valid(schema_path, 'foo', :clear_cache => false)
set_schema('type' => 'number')
refute_valid(schema_path, 123)
end
def test_clear_cache
set_schema('type' => 'string')
assert_valid(schema_path, 'foo', :clear_cache => true)
set_schema('type' => 'number')
assert_valid(schema_path, 123)
end
def test_cache_schemas
suppress_warnings do
JSON::Validator.cache_schemas = false
end
set_schema('type' => 'string')
assert_valid(schema_path, 'foo', :clear_cache => false)
set_schema('type' => 'number')
assert_valid(schema_path, 123)
ensure
suppress_warnings do
JSON::Validator.cache_schemas = true
end
end
private
def schema_path
@schema.path
end
def set_schema(schema_definition)
@schema.write(schema_definition.to_json)
@schema.rewind
end
end
ruby-json-schema-2.8.1/test/common_test_suite_test.rb 0000664 0000000 0000000 00000003562 13411675645 0023035 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
require 'json'
class CommonTestSuiteTest < Minitest::Test
TEST_DIR = File.expand_path('../test-suite/tests', __FILE__)
IGNORED_TESTS = YAML.load_file(File.expand_path('../support/test_suite_ignored_tests.yml', __FILE__))
def setup
Dir["#{TEST_DIR}/../remotes/**/*.json"].each do |path|
schema = path.sub(%r{^.*/remotes/}, '')
stub_request(:get, "http://localhost:1234/#{schema}").
to_return(:body => File.read(path), :status => 200)
end
end
def self.skip?(current_test, file_path)
skipped_in_file = file_path.chomp('.json').split('/').inject(IGNORED_TESTS) do |ignored, path_component|
ignored.nil? ? nil : ignored[path_component]
end
!skipped_in_file.nil? && (skipped_in_file == :all || skipped_in_file.include?(current_test))
end
Dir["#{TEST_DIR}/*"].each do |suite|
version = File.basename(suite).to_sym
Dir["#{suite}/**/*.json"].each do |tfile|
test_list = JSON.parse(File.read(tfile))
rel_file = tfile[TEST_DIR.length+1..-1]
test_list.each do |test|
schema = test["schema"]
base_description = test["description"]
test["tests"].each do |t|
full_description = "#{base_description}/#{t['description']}"
next if rel_file.include?('/optional/') && skip?(full_description, rel_file)
err_id = "#{rel_file}: #{full_description}"
define_method("test_#{err_id}") do
skip if self.class.skip?(full_description, rel_file)
errors = JSON::Validator.fully_validate(schema,
t["data"],
:parse_data => false,
:validate_schema => true,
:version => version
)
assert_equal t["valid"], errors.empty?, "Common test suite case failed: #{err_id}"
end
end
end
end
end
end
ruby-json-schema-2.8.1/test/custom_format_test.rb 0000664 0000000 0000000 00000012632 13411675645 0022155 0 ustar 00root root 0000000 0000000 # encoding: utf-8
require File.expand_path('../support/test_helper', __FILE__)
class CustomFormatTest < Minitest::Test
def setup
@all_versions = ['draft1', 'draft2', 'draft3', 'draft4', 'draft6', nil]
@format_proc = lambda { |value| raise JSON::Schema::CustomFormatError.new("must be 42") unless value == "42" }
@schema_6 = {
"$schema" => "http://json-schema.org/draft/schema#",
"properties" => {
"a" => {
"type" => "string",
"format" => "custom",
},
}
}
@schema_4 = @schema_6.clone
@schema_4["$schema"] = "http://json-schema.org/draft-04/schema#"
@schema_3 = @schema_6.clone
@schema_3["$schema"] = "http://json-schema.org/draft-03/schema#"
@schema_2 = @schema_6.clone
@schema_2["$schema"] = "http://json-schema.org/draft-02/schema#"
@schema_1 = @schema_6.clone
@schema_1["$schema"] = "http://json-schema.org/draft-01/schema#"
@default = @schema_6.clone
@default.delete("$schema")
@schemas = {
"draft1" => @schema_1,
"draft2" => @schema_2,
"draft3" => @schema_3,
"draft4" => @schema_4,
"draft6" => @schema_6,
nil => @default,
}
JSON::Validator.restore_default_formats
end
def test_single_registration
@all_versions.each do |version|
assert(JSON::Validator.validator_for_name(version).formats['custom'].nil?, "Format 'custom' for #{version || 'default'} should be nil")
JSON::Validator.register_format_validator("custom", @format_proc, [version])
assert(JSON::Validator.validator_for_name(version).formats['custom'].is_a?(JSON::Schema::CustomFormat), "Format 'custom' should be registered for #{version || 'default'}")
(@all_versions - [version]).each do |other_version|
assert(JSON::Validator.validator_for_name(other_version).formats['custom'].nil?, "Format 'custom' should still be nil for #{other_version || 'default'}")
end
JSON::Validator.deregister_format_validator("custom", [version])
assert(JSON::Validator.validator_for_name(version).formats['custom'].nil?, "Format 'custom' should be deregistered for #{version || 'default'}")
end
end
def test_register_for_all_by_default
JSON::Validator.register_format_validator("custom", @format_proc)
@all_versions.each do |version|
assert(JSON::Validator.validator_for_name(version).formats['custom'].is_a?(JSON::Schema::CustomFormat), "Format 'custom' should be registered for #{version || 'default'}")
end
JSON::Validator.restore_default_formats
@all_versions.each do |version|
assert(JSON::Validator.validator_for_name(version).formats['custom'].nil?, "Format 'custom' should still be nil for #{version || 'default'}")
end
end
def test_multi_registration
unregistered_version = @all_versions.delete("draft1")
JSON::Validator.register_format_validator("custom", @format_proc, @all_versions)
@all_versions.each do |version|
assert(JSON::Validator.validator_for_name(version).formats['custom'].is_a?(JSON::Schema::CustomFormat), "Format 'custom' should be registered for #{version || 'default'}")
end
assert(JSON::Validator.validator_for_name(unregistered_version).formats['custom'].nil?, "Format 'custom' should still be nil for #{unregistered_version}")
end
def test_format_validation
@all_versions.each do |version|
data = {
"a" => "23"
}
schema = @schemas[version]
prefix = "Validation for '#{version || 'default'}'"
assert(JSON::Validator.validate(schema, data), "#{prefix} succeeds with no 'custom' format validator registered")
JSON::Validator.register_format_validator("custom", @format_proc, [version])
data["a"] = "42"
assert(JSON::Validator.validate(schema, data), "#{prefix} succeeds with 'custom' format validator and correct data")
data["a"] = "23"
assert(!JSON::Validator.validate(schema, data), "#{prefix} fails with 'custom' format validator and wrong data")
errors = JSON::Validator.fully_validate(schema, data)
assert_equal(errors.count, 1)
assert_match(/The property '#\/a' must be 42 in schema/, errors.first, "#{prefix} records format error")
data["a"] = 23
errors = JSON::Validator.fully_validate(schema, data)
assert_equal(errors.count, 1)
assert_match(/The property '#\/a' of type integer did not match the following type: string/i, errors.first, "#{prefix} records no format error on type mismatch")
end
end
def test_override_default_format
@all_versions.each do |version|
data = {
"a" => "2001:db8:85a3:0:0:8a2e:370:7334"
}
schema = @schemas[version]
schema["properties"]["a"]["format"] = "ipv6"
prefix = "Validation for '#{version || 'default'}'"
assert(JSON::Validator.validate(schema, data), "#{prefix} succeeds for default format with correct data")
data["a"] = "no_ip6_address"
assert(!JSON::Validator.validate(schema, data), "#{prefix} fails for default format and wrong data")
data["a"] = "42"
JSON::Validator.register_format_validator("ipv6", @format_proc, [version])
assert(JSON::Validator.validate(schema, data), "#{prefix} succeeds with overriden default format and correct data")
JSON::Validator.deregister_format_validator("ipv6", [version])
data["a"] = "2001:db8:85a3:0:0:8a2e:370:7334"
assert(JSON::Validator.validate(schema, data), "#{prefix} restores the default format on deregistration")
end
end
end
ruby-json-schema-2.8.1/test/data/ 0000775 0000000 0000000 00000000000 13411675645 0016614 5 ustar 00root root 0000000 0000000 ruby-json-schema-2.8.1/test/data/all_of_ref_data.json 0000664 0000000 0000000 00000000026 13411675645 0022566 0 ustar 00root root 0000000 0000000 {
"name" : "john"
}
ruby-json-schema-2.8.1/test/data/any_of_ref_data.json 0000664 0000000 0000000 00000000076 13411675645 0022612 0 ustar 00root root 0000000 0000000 {
"names" :
[ "john"
, "jane"
, "jimmy"
]
}
ruby-json-schema-2.8.1/test/data/bad_data_1.json 0000664 0000000 0000000 00000000022 13411675645 0021440 0 ustar 00root root 0000000 0000000 {
"a" : "poop"
} ruby-json-schema-2.8.1/test/data/good_data_1.json 0000664 0000000 0000000 00000000015 13411675645 0021644 0 ustar 00root root 0000000 0000000 {
"a" : 5
} ruby-json-schema-2.8.1/test/data/one_of_ref_links_data.json 0000664 0000000 0000000 00000000233 13411675645 0023777 0 ustar 00root root 0000000 0000000 { "links":
[{ "rel" : ["self"] , "href":"http://api.example.com/api/object/3" }
,{ "rel" : ["up"] , "href":"http://api.example.com/api/object" }
]
}
ruby-json-schema-2.8.1/test/draft1_test.rb 0000664 0000000 0000000 00000005557 13411675645 0020464 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class Draft1Test < Minitest::Test
def validation_errors(schema, data, options)
super(schema, data, :version => :draft1)
end
def exclusive_minimum
{ 'minimumCanEqual' => false }
end
def exclusive_maximum
{ 'maximumCanEqual' => false }
end
include ArrayValidation::ItemsTests
include EnumValidation::General
include EnumValidation::V1_V2
include NumberValidation::MinMaxTests
include ObjectValidation::AdditionalPropertiesTests
include StrictValidation
include StringValidation::ValueTests
include StringValidation::FormatTests
include StringValidation::DateAndTimeFormatTests
include TypeValidation::SimpleTypeTests
include TypeValidation::AnyTypeTests
include TypeValidation::SchemaUnionTypeTests
def test_optional
# Set up the default datatype
schema = {
"properties" => {
"a" => {"type" => "string"}
}
}
data = {}
refute_valid schema, data
data['a'] = "Hello"
assert_valid schema, data
schema = {
"properties" => {
"a" => {"type" => "integer", "optional" => "true"}
}
}
data = {}
assert_valid schema, data
end
def test_max_decimal
# Set up the default datatype
schema = {
"properties" => {
"a" => {"maxDecimal" => 2}
}
}
data = {
"a" => nil
}
data["a"] = 3.35
assert_valid schema, data
data["a"] = 3.455
refute_valid schema, data
schema["properties"]["a"]["maxDecimal"] = 0
data["a"] = 4.0
refute_valid schema, data
data["a"] = 'boo'
assert_valid schema, data
data["a"] = 5
assert_valid schema, data
end
def test_disallow
# Set up the default datatype
schema = {
"properties" => {
"a" => {"disallow" => "integer"}
}
}
data = {
"a" => nil
}
data["a"] = 'string'
assert_valid schema, data
data["a"] = 5
refute_valid schema, data
schema["properties"]["a"]["disallow"] = ["integer","string"]
data["a"] = 'string'
refute_valid schema, data
data["a"] = 5
refute_valid schema, data
data["a"] = false
assert_valid schema, data
end
def test_format_datetime
schema = {
"type" => "object",
"properties" => { "a" => {"type" => "string", "format" => "date-time"}}
}
assert_valid schema, {"a" => "2010-01-01T12:00:00Z"}
refute_valid schema, {"a" => "2010-01-32T12:00:00Z"}
refute_valid schema, {"a" => "2010-13-01T12:00:00Z"}
refute_valid schema, {"a" => "2010-01-01T24:00:00Z"}
refute_valid schema, {"a" => "2010-01-01T12:60:00Z"}
refute_valid schema, {"a" => "2010-01-01T12:00:60Z"}
refute_valid schema, {"a" => "2010-01-01T12:00:00z"}
refute_valid schema, {"a" => "2010-01-0112:00:00Z"}
refute_valid schema, {"a" => "2010-01-01T12:00:00Z\nabc"}
end
end
ruby-json-schema-2.8.1/test/draft2_test.rb 0000664 0000000 0000000 00000004776 13411675645 0020467 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class Draft2Test < Minitest::Test
def validation_errors(schema, data, options)
super(schema, data, :version => :draft2)
end
def exclusive_minimum
{ 'minimumCanEqual' => false }
end
def exclusive_maximum
{ 'maximumCanEqual' => false }
end
def multiple_of
'divisibleBy'
end
include ArrayValidation::ItemsTests
include ArrayValidation::UniqueItemsTests
include EnumValidation::General
include EnumValidation::V1_V2
include NumberValidation::MinMaxTests
include NumberValidation::MultipleOfTests
include ObjectValidation::AdditionalPropertiesTests
include StrictValidation
include StringValidation::ValueTests
include StringValidation::FormatTests
include StringValidation::DateAndTimeFormatTests
include TypeValidation::SimpleTypeTests
include TypeValidation::AnyTypeTests
include TypeValidation::SchemaUnionTypeTests
def test_optional
# Set up the default datatype
schema = {
"properties" => {
"a" => {"type" => "string"}
}
}
data = {}
refute_valid schema, data
data['a'] = "Hello"
assert_valid schema, data
schema = {
"properties" => {
"a" => {"type" => "integer", "optional" => "true"}
}
}
data = {}
assert_valid schema, data
end
def test_disallow
# Set up the default datatype
schema = {
"properties" => {
"a" => {"disallow" => "integer"}
}
}
data = {
"a" => nil
}
data["a"] = 'string'
assert_valid schema, data
data["a"] = 5
refute_valid schema, data
schema["properties"]["a"]["disallow"] = ["integer","string"]
data["a"] = 'string'
refute_valid schema, data
data["a"] = 5
refute_valid schema, data
data["a"] = false
assert_valid schema, data
end
def test_format_datetime
schema = {
"type" => "object",
"properties" => { "a" => {"type" => "string", "format" => "date-time"}}
}
assert_valid schema, {"a" => "2010-01-01T12:00:00Z"}
refute_valid schema, {"a" => "2010-01-32T12:00:00Z"}
refute_valid schema, {"a" => "2010-13-01T12:00:00Z"}
refute_valid schema, {"a" => "2010-01-01T24:00:00Z"}
refute_valid schema, {"a" => "2010-01-01T12:60:00Z"}
refute_valid schema, {"a" => "2010-01-01T12:00:60Z"}
refute_valid schema, {"a" => "2010-01-01T12:00:00z"}
refute_valid schema, {"a" => "2010-01-0112:00:00Z"}
refute_valid schema, {"a" => "2010-01-01T12:00:00Z\nabc"}
end
end
ruby-json-schema-2.8.1/test/draft3_test.rb 0000664 0000000 0000000 00000030201 13411675645 0020446 0 ustar 00root root 0000000 0000000 # encoding: utf-8
require File.expand_path('../support/test_helper', __FILE__)
class Draft3Test < Minitest::Test
def validation_errors(schema, data, options)
super(schema, data, :version => :draft3)
end
def exclusive_minimum
{ 'exclusiveMinimum' => true }
end
def exclusive_maximum
{ 'exclusiveMaximum' => true }
end
def multiple_of
'divisibleBy'
end
include ArrayValidation::ItemsTests
include ArrayValidation::AdditionalItemsTests
include ArrayValidation::UniqueItemsTests
include EnumValidation::General
include EnumValidation::V3_V4
include NumberValidation::MinMaxTests
include NumberValidation::MultipleOfTests
include ObjectValidation::AdditionalPropertiesTests
include ObjectValidation::PatternPropertiesTests
include StrictValidation
include StringValidation::ValueTests
include StringValidation::FormatTests
include StringValidation::DateAndTimeFormatTests
include TypeValidation::SimpleTypeTests
include TypeValidation::AnyTypeTests
include TypeValidation::SchemaUnionTypeTests
def test_types
# Set up the default datatype
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"properties" => {
"a" => {}
}
}
data = {
"a" => nil
}
# Test an array of unioned-type objects that prevent additionalProperties
schema["properties"]["a"] = {
'type' => 'array',
'items' => {
'type' => [
{ 'type' => 'object', 'properties' => { "b" => { "type" => "integer" } } },
{ 'type' => 'object', 'properties' => { "c" => { "type" => "string" } } }
],
'additionalProperties' => false
}
}
data["a"] = [{"b" => 5}, {"c" => "foo"}]
errors = JSON::Validator.fully_validate(schema, data)
assert(errors.empty?, errors.join("\n"))
# This should actually pass, because this matches the first schema in the union
data["a"] << {"c" => false}
assert_valid schema, data
end
def test_required
# Set up the default datatype
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"properties" => {
"a" => {"required" => true}
}
}
data = {}
refute_valid schema, data
data['a'] = "Hello"
assert_valid schema, data
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"properties" => {
"a" => {"type" => "integer"}
}
}
data = {}
assert_valid schema, data
end
def test_strict_properties_required_props
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"properties" => {
"a" => {"type" => "string", "required" => true},
"b" => {"type" => "string", "required" => false}
}
}
data = {"a" => "a"}
assert(JSON::Validator.validate(schema,data,:strict => true))
data = {"b" => "b"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b"}
assert(JSON::Validator.validate(schema,data,:strict => true))
end
def test_strict_properties_additional_props
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"properties" => {
"a" => {"type" => "string"},
"b" => {"type" => "string"}
},
"additionalProperties" => {"type" => "integer"}
}
data = {"a" => "a"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"b" => "b"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b"}
assert(JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b", "c" => "c"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b", "c" => 3}
assert(JSON::Validator.validate(schema,data,:strict => true))
end
def test_strict_properties_pattern_props
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"properties" => {
"a" => {"type" => "string"},
"b" => {"type" => "string"}
},
"patternProperties" => {"\\d+ taco" => {"type" => "integer"}}
}
data = {"a" => "a"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"b" => "b"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b"}
assert(JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b", "c" => "c"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b", "c" => 3}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b", "23 taco" => 3}
assert(JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b", "23 taco" => "cheese"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
end
def test_disallow
# Set up the default datatype
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"properties" => {
"a" => {"disallow" => "integer"}
}
}
data = {
"a" => nil
}
data["a"] = 'string'
assert_valid schema, data
data["a"] = 5
refute_valid schema, data
schema["properties"]["a"]["disallow"] = ["integer","string"]
data["a"] = 'string'
refute_valid schema, data
data["a"] = 5
refute_valid schema, data
data["a"] = false
assert_valid schema, data
end
def test_extends
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"properties" => {
"a" => { "type" => "integer"}
}
}
schema2 = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"properties" => {
"a" => { "maximum" => 5 }
}
}
data = {
"a" => 10
}
assert_valid schema, data
assert(!JSON::Validator.validate(schema2,data))
schema["extends"] = schema2
refute_valid schema, data
end
def test_list_option
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"type" => "object",
"properties" => { "a" => {"type" => "integer", "required" => true} }
}
data = [{"a" => 1},{"a" => 2},{"a" => 3}]
assert(JSON::Validator.validate(schema,data,:list => true))
refute_valid schema, data
data = {"a" => 1}
assert(!JSON::Validator.validate(schema,data,:list => true))
data = [{"a" => 1},{"b" => 2},{"a" => 3}]
assert(!JSON::Validator.validate(schema,data,:list => true))
end
def test_self_reference
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"type" => "object",
"properties" => { "a" => {"type" => "integer"}, "b" => {"$ref" => "#"}}
}
assert_valid schema, {"a" => 5, "b" => {"b" => {"a" => 1}}}
refute_valid schema, {"a" => 5, "b" => {"b" => {"a" => 'taco'}}}
end
def test_format_datetime
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"type" => "object",
"properties" => { "a" => {"type" => "string", "format" => "date-time"}}
}
assert_valid schema, {"a" => "2010-01-01T12:00:00Z"}
assert_valid schema, {"a" => "2010-01-01T12:00:00.1Z"}
assert_valid schema, {"a" => "2010-01-01T12:00:00,1Z"}
refute_valid schema, {"a" => "2010-01-32T12:00:00Z"}
refute_valid schema, {"a" => "2010-13-01T12:00:00Z"}
refute_valid schema, {"a" => "2010-01-01T24:00:00Z"}
refute_valid schema, {"a" => "2010-01-01T12:60:00Z"}
refute_valid schema, {"a" => "2010-01-01T12:00:60Z"}
refute_valid schema, {"a" => "2010-01-01T12:00:00z"}
refute_valid schema, {"a" => "2010-01-0112:00:00Z"}
refute_valid schema, {"a" => "2010-01-01T12:00:00.1Z\nabc"}
# test with a specific timezone
assert_valid schema, {"a" => "2010-01-01T12:00:00+01"}
assert_valid schema, {"a" => "2010-01-01T12:00:00+01:00"}
assert_valid schema, {"a" => "2010-01-01T12:00:00+01:30"}
assert_valid schema, {"a" => "2010-01-01T12:00:00+0234"}
refute_valid schema, {"a" => "2010-01-01T12:00:00+01:"}
refute_valid schema, {"a" => "2010-01-01T12:00:00+0"}
# do not allow mixing Z and specific timezone
refute_valid schema, {"a" => "2010-01-01T12:00:00Z+01"}
refute_valid schema, {"a" => "2010-01-01T12:00:00+01Z"}
refute_valid schema, {"a" => "2010-01-01T12:00:00+01:30Z"}
refute_valid schema, {"a" => "2010-01-01T12:00:00+0Z"}
# test without any timezone
assert_valid schema, {"a" => "2010-01-01T12:00:00"}
assert_valid schema, {"a" => "2010-01-01T12:00:00.12345"}
assert_valid schema, {"a" => "2010-01-01T12:00:00,12345"}
assert_valid schema, {"a" => "2010-01-01T12:00:00.12345"}
end
def test_format_uri
data1 = {"a" => "http://gitbuh.com"}
data2 = {"a" => "::boo"}
data3 = {"a" => "http://ja.wikipedia.org/wiki/メインページ"}
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"type" => "object",
"properties" => { "a" => {"type" => "string", "format" => "uri"}}
}
assert(JSON::Validator.validate(schema,data1))
assert(!JSON::Validator.validate(schema,data2))
assert(JSON::Validator.validate(schema,data3))
end
def test_schema
schema = {
"$schema" => "http://json-schema.org/THIS-IS-NOT-A-SCHEMA",
"type" => "object"
}
data = {"a" => "taco"}
assert(!JSON::Validator.validate(schema, data))
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"type" => "object"
}
assert_valid schema, data
end
def test_dependency
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"type" => "object",
"properties" => {
"a" => {"type" => "integer"},
"b" => {"type" => "integer"}
},
"dependencies" => {
"a" => "b"
}
}
data = {"a" => 1, "b" => 2}
assert_valid schema, data
data = {"a" => 1}
refute_valid schema, data
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"type" => "object",
"properties" => {
"a" => {"type" => "integer"},
"b" => {"type" => "integer"},
"c" => {"type" => "integer"}
},
"dependencies" => {
"a" => ["b","c"]
}
}
data = {"a" => 1, "c" => 2}
refute_valid schema, data
data = {"a" => 1, "b" => 2, "c" => 3}
assert_valid schema, data
end
def test_default
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"type" => "object",
"properties" => {
"a" => {"type" => "integer", "default" => 42},
"b" => {"type" => "integer"}
}
}
data = {:b => 2}
assert_valid schema, data
assert_nil(data["a"])
assert(JSON::Validator.validate(schema,data, :insert_defaults => true))
assert_equal(42, data["a"])
assert_equal(2, data[:b])
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"type" => "object",
"properties" => {
"a" => {"type" => "integer", "default" => 42, "required" => true},
"b" => {"type" => "integer"}
}
}
data = {:b => 2}
refute_valid schema, data
assert_nil(data["a"])
assert(JSON::Validator.validate(schema,data, :insert_defaults => true))
assert_equal(42, data["a"])
assert_equal(2, data[:b])
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"type" => "object",
"properties" => {
"a" => {"type" => "integer", "default" => 42, "required" => true, "readonly" => true},
"b" => {"type" => "integer"}
}
}
data = {:b => 2}
refute_valid schema, data
assert_nil(data["a"])
assert(!JSON::Validator.validate(schema,data, :insert_defaults => true))
assert_nil(data["a"])
assert_equal(2, data[:b])
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"type" => "object",
"properties" => {
"a" => {"type" => "integer", "default" => "42"},
"b" => {"type" => "integer"}
}
}
data = {:b => 2}
assert_valid schema, data
assert_nil(data["a"])
assert(!JSON::Validator.validate(schema,data, :insert_defaults => true))
assert_equal("42",data["a"])
assert_equal(2, data[:b])
end
end
ruby-json-schema-2.8.1/test/draft4_test.rb 0000664 0000000 0000000 00000041621 13411675645 0020457 0 ustar 00root root 0000000 0000000 # encoding: utf-8
require File.expand_path('../support/test_helper', __FILE__)
class Draft4Test < Minitest::Test
def validation_errors(schema, data, options)
super(schema, data, :version => :draft4)
end
def exclusive_minimum
{ 'exclusiveMinimum' => true }
end
def exclusive_maximum
{ 'exclusiveMaximum' => true }
end
def ipv4_format
'ipv4'
end
include ArrayValidation::ItemsTests
include ArrayValidation::AdditionalItemsTests
include ArrayValidation::UniqueItemsTests
include EnumValidation::General
include EnumValidation::V3_V4
include NumberValidation::MinMaxTests
include NumberValidation::MultipleOfTests
include ObjectValidation::AdditionalPropertiesTests
include ObjectValidation::PatternPropertiesTests
include StrictValidation
include StringValidation::ValueTests
include StringValidation::FormatTests
include TypeValidation::SimpleTypeTests
def test_required
# Set up the default datatype
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"required" => ["a"],
"properties" => {
"a" => {}
}
}
data = {}
refute_valid schema, data
data['a'] = "Hello"
assert_valid schema, data
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"properties" => {
"a" => {"type" => "integer"}
}
}
data = {}
assert_valid schema, data
end
def test_min_properties
schema = { 'minProperties' => 2 }
assert_valid schema, {'a' => 1, 'b' => 2}
assert_valid schema, {'a' => 1, 'b' => 2, 'c' => 3}
refute_valid schema, {'a' => 1}
refute_valid schema, {}
end
def test_max_properties
schema = { 'maxProperties' => 2 }
assert_valid schema, {'a' => 1, 'b' => 2}
assert_valid schema, {'a' => 1}
assert_valid schema, {}
refute_valid schema, {'a' => 1, 'b' => 2, 'c' => 3}
end
def test_strict_properties
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"properties" => {
"a" => {"type" => "string"},
"b" => {"type" => "string"}
}
}
data = {"a" => "a"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"b" => "b"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b"}
assert(JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b", "c" => "c"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
end
def test_strict_properties_additional_props
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"properties" => {
"a" => {"type" => "string"},
"b" => {"type" => "string"}
},
"additionalProperties" => {"type" => "integer"}
}
data = {"a" => "a"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"b" => "b"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b"}
assert(JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b", "c" => "c"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b", "c" => 3}
assert(JSON::Validator.validate(schema,data,:strict => true))
end
def test_strict_properties_pattern_props
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"properties" => {
"a" => {"type" => "string"},
"b" => {"type" => "string"}
},
"patternProperties" => {"\\d+ taco" => {"type" => "integer"}}
}
data = {"a" => "a"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"b" => "b"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b"}
assert(JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b", "c" => "c"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b", "c" => 3}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b", "23 taco" => 3}
assert(JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b", "23 taco" => "cheese"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
end
def test_list_option
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"type" => "object",
"required" => ["a"],
"properties" => { "a" => {"type" => "integer"} }
}
data = [{"a" => 1},{"a" => 2},{"a" => 3}]
assert(JSON::Validator.validate(schema,data,:list => true))
refute_valid schema, data
data = {"a" => 1}
assert(!JSON::Validator.validate(schema,data,:list => true))
data = [{"a" => 1},{"b" => 2},{"a" => 3}]
assert(!JSON::Validator.validate(schema,data,:list => true))
end
def test_default_with_strict_and_anyof
schema = {
"anyOf" => [
{
"type" => "object",
"properties" => {
"foo" => {
"enum" => ["view", "search"],
"default" => "view"
}
}
},
{
"type" => "object",
"properties" => {
"bar" => {
"type" => "string"
}
}
}
]
}
data = {
"bar" => "baz"
}
assert(JSON::Validator.validate(schema, data, :insert_defaults => true, :strict => true))
end
def test_default_with_anyof
schema = {
"anyOf" => [
{
"type" => "object",
"properties" => {
"foo" => {
"enum" => ["view", "search"],
"default" => "view"
}
}
},
{
"type" => "object",
"properties" => {
"bar" => {
"type" => "string"
}
}
}
]
}
data = {}
assert(JSON::Validator.validate(schema, data, :insert_defaults => true, :strict => true))
assert(data['foo'] == 'view')
end
def test_default_with_strict_and_oneof
schema = {
"oneOf" => [
{
"type" => "object",
"properties" => {
"bar" => {
"type" => "string"
}
}
},
{
"type" => "object",
"properties" => {
"foo" => {
"enum" => ["view", "search"],
"default" => "view"
}
}
}
]
}
data = {
"bar" => "baz"
}
assert(JSON::Validator.validate(schema, data, :insert_defaults => true, :strict => true))
assert(!data.key?('foo'))
end
def test_self_reference
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"type" => "object",
"properties" => { "a" => {"type" => "integer"}, "b" => {"$ref" => "#"}}
}
assert_valid schema, {"a" => 5, "b" => {"b" => {"a" => 1}}}
refute_valid schema, {"a" => 5, "b" => {"b" => {"a" => 'taco'}}}
end
def test_property_named_ref
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"properties" => {
"$ref" => {
"type" => "integer"
}
}
}
assert_valid schema, { "$ref" => 1 }
refute_valid schema, { "$ref" => "#" }
end
def test_format_datetime
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"type" => "object",
"properties" => { "a" => {"type" => "string", "format" => "date-time"}}
}
assert_valid schema, {"a" => "2010-01-01T12:00:00Z"}
assert_valid schema, {"a" => "2010-01-01T12:00:00.1Z"}
refute_valid schema, {"a" => "2010-01-01T12:00:00,1Z"}
refute_valid schema, {"a" => "2010-01-01T12:00:00+0000"}
assert_valid schema, {"a" => "2010-01-01T12:00:00+00:00"}
refute_valid schema, {"a" => "2010-01-32T12:00:00Z"}
refute_valid schema, {"a" => "2010-13-01T12:00:00Z"}
assert_valid schema, {"a" => "2010-01-01T24:00:00Z"}
refute_valid schema, {"a" => "2010-01-01T12:60:00Z"}
assert_valid schema, {"a" => "2010-01-01T12:00:60Z"}
assert_valid schema, {"a" => "2010-01-01T12:00:00z"}
refute_valid schema, {"a" => "2010-01-0112:00:00Z"}
end
def test_format_uri
data1 = {"a" => "http://gitbuh.com"}
data2 = {"a" => "::boo"}
data3 = {"a" => "http://ja.wikipedia.org/wiki/メインページ"}
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"type" => "object",
"properties" => { "a" => {"type" => "string", "format" => "uri"}}
}
assert(JSON::Validator.validate(schema,data1))
assert(!JSON::Validator.validate(schema,data2))
assert(JSON::Validator.validate(schema,data3))
end
def test_schema
schema = {
"$schema" => "http://json-schema.org/THIS-IS-NOT-A-SCHEMA",
"type" => "object"
}
data = {"a" => "taco"}
assert(!JSON::Validator.validate(schema,data))
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"type" => "object"
}
assert_valid schema, data
end
def test_dependency
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"type" => "object",
"properties" => {
"a" => {"type" => "integer"},
"b" => {"type" => "integer"}
},
"dependencies" => {
"a" => ["b"]
}
}
data = {"a" => 1, "b" => 2}
assert_valid schema, data
data = {"a" => 1}
refute_valid schema, data
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"type" => "object",
"properties" => {
"a" => {"type" => "integer"},
"b" => {"type" => "integer"},
"c" => {"type" => "integer"}
},
"dependencies" => {
"a" => ["b","c"]
}
}
data = {"a" => 1, "c" => 2}
refute_valid schema, data
data = {"a" => 1, "b" => 2, "c" => 3}
assert_valid schema, data
end
def test_schema_dependency
schema = {
"type"=> "object",
"properties"=> {
"name"=> { "type"=> "string" },
"credit_card"=> { "type"=> "number" }
},
"required"=> ["name"],
"dependencies"=> {
"credit_card"=> {
"properties"=> {
"billing_address"=> { "type"=> "string" }
},
"required"=> ["billing_address"]
}
}
}
data = {
"name" => "John Doe",
"credit_card" => 5555555555555555
}
assert(!JSON::Validator.validate(schema,data), 'test schema dependency with invalid data')
data['billing_address'] = "Somewhere over the rainbow"
assert(JSON::Validator.validate(schema,data), 'test schema dependency with valid data')
end
def test_default
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"type" => "object",
"properties" => {
"a" => {"type" => "integer", "default" => 42},
"b" => {"type" => "integer"}
}
}
data = {:b => 2}
assert_valid schema, data
assert_nil(data["a"])
assert(JSON::Validator.validate(schema,data, :insert_defaults => true))
assert_equal(42, data["a"])
assert_equal(2, data[:b])
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"type" => "object",
"required" => ["a"],
"properties" => {
"a" => {"type" => "integer", "default" => 42},
"b" => {"type" => "integer"}
}
}
data = {:b => 2}
refute_valid schema, data
assert_nil(data["a"])
assert(JSON::Validator.validate(schema,data, :insert_defaults => true))
assert_equal(42, data["a"])
assert_equal(2, data[:b])
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"type" => "object",
"required" => ["a"],
"properties" => {
"a" => {"type" => "integer", "default" => 42, "readonly" => true},
"b" => {"type" => "integer"}
}
}
data = {:b => 2}
refute_valid schema, data
assert_nil(data["a"])
assert(!JSON::Validator.validate(schema,data, :insert_defaults => true))
assert_nil(data["a"])
assert_equal(2, data[:b])
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"type" => "object",
"properties" => {
"a" => {"type" => "integer", "default" => "42"},
"b" => {"type" => "integer"}
}
}
data = {:b => 2}
assert_valid schema, data
assert_nil(data["a"])
assert(!JSON::Validator.validate(schema,data, :insert_defaults => true))
assert_equal("42",data["a"])
assert_equal(2, data[:b])
end
def test_boolean_false_default
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"type" => "object",
"required" => ["a"],
"properties" => {
"a" => {"type" => "boolean", "default" => false},
"b" => {"type" => "integer"}
}
}
data = {:b => 2}
refute_valid schema, data
assert_nil(data["a"])
assert(JSON::Validator.validate(schema, data, :insert_defaults => true))
assert_equal(false, data["a"])
assert_equal(2, data[:b])
end
def test_all_of
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"allOf" => [
{
"properties" => {"a" => {"type" => "string"}},
"required" => ["a"]
},
{
"properties" => {"b" => {"type" => "integer"}}
}
]
}
data = {"a" => "hello", "b" => 5}
assert_valid schema, data
data = {"a" => "hello"}
assert_valid schema, data
data = {"a" => "hello", "b" => "taco"}
refute_valid schema, data
data = {"b" => 5}
refute_valid schema, data
end
def test_any_of
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"anyOf" => [
{
"properties" => {"a" => {"type" => "string"}},
"required" => ["a"]
},
{
"properties" => {"b" => {"type" => "integer"}}
}
]
}
data = {"a" => "hello", "b" => 5}
assert_valid schema, data
data = {"a" => "hello"}
assert_valid schema, data
data = {"a" => "hello", "b" => "taco"}
assert_valid schema, data
data = {"b" => 5}
assert_valid schema, data
data = {"a" => 5, "b" => "taco"}
refute_valid schema, data
end
def test_one_of
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"oneOf" => [
{
"properties" => {"a" => {"type" => "string"}},
"required" => ["a"]
},
{
"properties" => {"b" => {"type" => "integer"}}
}
]
}
data = {"a" => "hello", "b" => 5}
refute_valid schema, data
# This passes because b is not required, thus matches both schemas
data = {"a" => "hello"}
refute_valid schema, data
data = {"a" => "hello", "b" => "taco"}
assert_valid schema, data
data = {"b" => 5}
assert_valid schema, data
data = {"a" => 5, "b" => "taco"}
refute_valid schema, data
end
def test_not
# Start with a simple not
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"properties" => {
"a" => {"not" => { "type" => ["string", "boolean"]}}
}
}
data = {"a" => 1}
assert_valid schema, data
data = {"a" => "hi!"}
refute_valid schema, data
data = {"a" => true}
refute_valid schema, data
# Sub-schema not
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"properties" => {
"a" => {"not" => {"anyOf" => [
{
"type" => ["string","boolean"]
},
{
"type" => "object",
"properties" => {
"b" => {"type" => "boolean"}
}
}
]}
}
}
}
data = {"a" => 1}
assert_valid schema, data
data = {"a" => "hi!"}
refute_valid schema, data
data = {"a" => true}
refute_valid schema, data
data = {"a" => {"b" => true}}
refute_valid schema, data
data = {"a" => {"b" => 5}}
assert_valid schema, data
end
def test_not_fully_validate
# Start with a simple not
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"properties" => {
"a" => {"not" => { "type" => ["string", "boolean"]}}
}
}
data = {"a" => 1}
errors = JSON::Validator.fully_validate(schema,data)
assert_equal(0, errors.length)
data = {"a" => "taco"}
errors = JSON::Validator.fully_validate(schema,data)
assert_equal(1, errors.length)
end
def test_definitions
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"type" => "array",
"items" => { "$ref" => "#/definitions/positiveInteger"},
"definitions" => {
"positiveInteger" => {
"type" => "integer",
"minimum" => 0,
"exclusiveMinimum" => true
}
}
}
data = [1,2,3]
assert_valid schema, data
data = [-1,2,3]
refute_valid schema, data
end
end
ruby-json-schema-2.8.1/test/extended_schema_test.rb 0000664 0000000 0000000 00000003460 13411675645 0022412 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class ExtendedSchemaTest < Minitest::Test
class BitwiseAndAttribute < JSON::Schema::Attribute
def self.validate(current_schema, data, fragments, processor, validator, options = {})
return unless data.is_a?(Integer)
if 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-and']}"
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
@names = ["http://test.com/test.json"]
@uri = Addressable::URI.parse("http://test.com/test.json")
@names = ["http://test.com/test.json"]
end
JSON::Validator.register_validator(ExtendedSchema.new)
end
def test_extended_schema_validation
schema = {
"$schema" => "http://test.com/test.json",
"properties" => {
"a" => {
"bitwise-and" => 1
},
"b" => {
"type" => "string"
}
}
}
assert_valid schema, {"a" => 1, "b" => "taco"}
refute_valid schema, {"a" => 0, "b" => "taco"}
refute_valid schema, {"a" => 1, "b" => 5}
end
def test_unextended_schema
# Verify that using the original schema disregards the `bitwise-and` property
schema = {
"properties" => {
"a" => {
"bitwise-and" => 1
},
"b" => {
"type" => "string"
}
}
}
assert_valid schema, {"a" => 0, "b" => "taco"}
assert_valid schema, {"a" => 1, "b" => "taco"}
refute_valid schema, {"a" => 1, "b" => 5}
end
end
ruby-json-schema-2.8.1/test/extends_nested_test.rb 0000664 0000000 0000000 00000002624 13411675645 0022307 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class ExtendsNestedTest < Minitest::Test
ADDITIONAL_PROPERTIES = ['extends_and_additionalProperties_false_schema.json']
PATTERN_PROPERTIES = ['extends_and_patternProperties_schema.json']
ALL_SCHEMAS = ADDITIONAL_PROPERTIES + PATTERN_PROPERTIES
def test_valid_outer
ALL_SCHEMAS.each do |file|
path = schema_fixture_path(file)
assert_valid path, { "outerC" => true }, {}, "Outer defn is broken, maybe the outer extends overrode it"
end
end
def test_valid_outer_extended
ALL_SCHEMAS.each do |file|
path = schema_fixture_path(file)
assert_valid path, { "innerA" => true }, {}, "Extends at the root level isn't working"
end
end
def test_valid_inner
ALL_SCHEMAS.each do |file|
path = schema_fixture_path(file)
assert_valid path, { "outerB" => [{ "innerA" => true }] }, {}, "Extends isn't working in the array element defn"
end
end
def test_invalid_inner
ALL_SCHEMAS.each do |file|
path = schema_fixture_path(file)
refute_valid path, { "outerB" => [{ "whaaaaat" => true }] }, {}, "Array element defn allowing anything when it should only allow what's in inner.schema"
end
end
def test_invalid_outer
path = schema_fixture_path(ADDITIONAL_PROPERTIES)
refute_valid path, { "whaaaaat" => true }, {}, "Outer defn allowing anything when it shouldn't"
end
end
ruby-json-schema-2.8.1/test/files_test.rb 0000664 0000000 0000000 00000004333 13411675645 0020374 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class FilesTest < Minitest::Test
#
# These tests are ONLY run if there is an appropriate JSON backend parser available
#
def test_schema_from_file
assert_valid schema_fixture_path('good_schema_1.json'), { "a" => 5 }
refute_valid schema_fixture_path('good_schema_1.json'), { "a" => "bad" }
end
def test_data_from_file_v3
schema = {"$schema" => "http://json-schema.org/draft-03/schema#","type" => "object", "properties" => {"a" => {"type" => "integer"}}}
assert_valid schema, data_fixture_path('good_data_1.json'), :uri => true
refute_valid schema, data_fixture_path('bad_data_1.json'), :uri => true
end
def test_data_from_json_v3
schema = {"$schema" => "http://json-schema.org/draft-03/schema#","type" => "object", "properties" => {"a" => {"type" => "integer"}}}
assert_valid schema, %Q({"a": 5}), :json => true
refute_valid schema, %Q({"a": "poop"}), :json => true
end
def test_data_from_file_v4
schema = {"$schema" => "http://json-schema.org/draft-04/schema#","type" => "object", "properties" => {"a" => {"type" => "integer"}}}
assert_valid schema, data_fixture_path('good_data_1.json'), :uri => true
refute_valid schema, data_fixture_path('bad_data_1.json'), :uri => true
end
def test_data_from_json_v4
schema = {"$schema" => "http://json-schema.org/draft-04/schema#","type" => "object", "properties" => {"a" => {"type" => "integer"}}}
assert_valid schema, %Q({"a": 5}), :json => true
refute_valid schema, %Q({"a": "poop"}), :json => true
end
def test_both_from_file
assert_valid schema_fixture_path('good_schema_1.json'), data_fixture_path('good_data_1.json'), :uri => true
refute_valid schema_fixture_path('good_schema_1.json'), data_fixture_path('bad_data_1.json'), :uri => true
end
def test_file_ref
assert_valid schema_fixture_path('good_schema_2.json'), { "b" => { "a" => 5 } }
refute_valid schema_fixture_path('good_schema_1.json'), { "b" => { "a" => "boo" } }
end
def test_file_extends
assert_valid schema_fixture_path('good_schema_extends1.json'), { "a" => 5 }
assert_valid schema_fixture_path('good_schema_extends2.json'), { "a" => 5, "b" => { "a" => 5 } }
end
end
ruby-json-schema-2.8.1/test/fragment_resolution_test.rb 0000664 0000000 0000000 00000004035 13411675645 0023357 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class FragmentResolutionTest < Minitest::Test
def test_fragment_resolution
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"required" => ["a"],
"properties" => {
"a" => {
"type" => "object",
"properties" => {
"b" => {"type" => "integer" }
}
}
}
}
data = {"b" => 5}
refute_valid schema, data
assert_valid schema, data, :fragment => "#/properties/a"
assert_raises JSON::Schema::SchemaError do
JSON::Validator.validate!(schema,data,:fragment => "/properties/a")
end
assert_raises JSON::Schema::SchemaError do
JSON::Validator.validate!(schema,data,:fragment => "#/properties/b")
end
end
def test_odd_level_fragment_resolution
schema = {
"foo" => {
"type" => "object",
"required" => ["a"],
"properties" => {
"a" => {"type" => "integer"}
}
}
}
assert_valid schema, {"a" => 1}, :fragment => "#/foo"
refute_valid schema, {}, :fragment => "#/foo"
end
def test_even_level_fragment_resolution
schema = {
"foo" => {
"bar" => {
"type" => "object",
"required" => ["a"],
"properties" => {
"a" => {"type" => "integer"}
}
}
}
}
assert_valid schema, {"a" => 1}, :fragment => "#/foo/bar"
refute_valid schema, {}, :fragment => "#/foo/bar"
end
def test_array_fragment_resolution
schema = {
"type" => "object",
"required" => ["a"],
"properties" => {
"a" => {
"anyOf" => [
{"type" => "integer"},
{"type" => "string"}
]
}
}
}
refute_valid schema, "foo", :fragment => "#/properties/a/anyOf/0"
assert_valid schema, "foo", :fragment => "#/properties/a/anyOf/1"
assert_valid schema, 5, :fragment => "#/properties/a/anyOf/0"
refute_valid schema, 5, :fragment => "#/properties/a/anyOf/1"
end
end
ruby-json-schema-2.8.1/test/fragment_validation_with_ref_test.rb 0000664 0000000 0000000 00000003216 13411675645 0025175 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class FragmentValidationWithRefTest < Minitest::Test
def whole_schema
{
"$schema" => "http://json-schema.org/draft-04/schema#",
"type" => "object",
"definitions" => {
"post" => {
"type" => "object",
"properties" => {
"content" => {
"type" => "string"
},
"author" => {
"type" => "string"
}
}
},
"posts" => {
"type" => "array",
"items" => {
"$ref" => "#/definitions/post"
}
}
}
}
end
def whole_schema_with_array
{
"$schema" => "http://json-schema.org/draft-04/schema#",
"type" => "object",
"definitions" => {
"omg" => {
"links" => [
{
"type" => "object",
"schema" => {
"properties" => {
"content" => {
"type" => "string"
},
"author" => {
"type" => "string"
}
},
"required" => ["content", "author"]
}
}
]
}
}
}
end
def test_validation_of_fragment
data = [{"content" => "ohai", "author" => "Bob"}]
assert_valid whole_schema, data, :fragment => "#/definitions/posts"
end
def test_validation_of_fragment_with_array
data = {"content" => "ohai", "author" => "Bob"}
assert_valid(whole_schema_with_array, data,
:fragment => "#/definitions/omg/links/0/schema")
end
end
ruby-json-schema-2.8.1/test/full_validation_test.rb 0000664 0000000 0000000 00000011623 13411675645 0022446 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class FullValidationTest < Minitest::Test
def test_full_validation
data = {"b" => {"a" => 5}}
schema = {
"type" => "object",
"required" => ["b"],
"properties" => {
"b" => {
}
}
}
errors = JSON::Validator.fully_validate(schema,data)
assert(errors.empty?)
data = {"c" => 5}
schema = {
"type" => "object",
"required" => ["b"],
"properties" => {
"b" => {
},
"c" => {
"type" => "string"
}
}
}
errors = JSON::Validator.fully_validate(schema,data)
assert(errors.length == 2)
end
def test_full_validation_with_union_types
data = {"b" => 5}
schema = {
"type" => "object",
"properties" => {
"b" => {
"type" => ["null","integer"]
}
}
}
errors = JSON::Validator.fully_validate(schema,data)
assert(errors.empty?)
schema = {
"type" => "object",
"properties" => {
"b" => {
"type" => ["integer","null"]
}
}
}
errors = JSON::Validator.fully_validate(schema,data)
assert(errors.empty?)
data = {"b" => "a string"}
errors = JSON::Validator.fully_validate(schema,data)
assert(errors.length == 1)
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"type" => "object",
"properties" => {
"b" => {
"type" => [
{
"type" => "object",
"properties" => {
"c" => {"type" => "string"}
}
},
{
"type" => "object",
"properties" => {
"d" => {"type" => "integer"}
}
}
]
}
}
}
data = {"b" => {"c" => "taco"}}
errors = JSON::Validator.fully_validate(schema,data)
assert(errors.empty?)
data = {"b" => {"d" => 6}}
errors = JSON::Validator.fully_validate(schema,data)
assert(errors.empty?)
data = {"b" => {"c" => 6, "d" => "OH GOD"}}
errors = JSON::Validator.fully_validate(schema,data)
assert(errors.length == 1)
end
def test_full_validation_with_object_errors
data = {"b" => {"a" => 5}}
schema = {
"type" => "object",
"required" => ["b"],
"properties" => {
"b" => {
}
}
}
errors = JSON::Validator.fully_validate(schema,data,:errors_as_objects => true)
assert(errors.empty?)
data = {"c" => 5}
schema = {
"type" => "object",
"required" => ["b"],
"properties" => {
"b" => {
},
"c" => {
"type" => "string"
}
}
}
errors = JSON::Validator.fully_validate(schema,data,:errors_as_objects => true)
assert(errors.length == 2)
assert(errors[0][:failed_attribute] == "Required")
assert(errors[0][:fragment] == "#/")
assert(errors[1][:failed_attribute] == "TypeV4")
assert(errors[1][:fragment] == "#/c")
end
def test_full_validation_with_nested_required_properties
schema = {
"type" => "object",
"required" => ["x"],
"properties" => {
"x" => {
"type" => "object",
"required" => ["a", "b"],
"properties" => {
"a" => {"type"=>"integer"},
"b" => {"type"=>"integer"},
"c" => {"type"=>"integer"},
"d" => {"type"=>"integer"},
"e" => {"type"=>"integer"},
}
}
}
}
data = {"x" => {"a"=>5, "d"=>5, "e"=>"what?"}}
errors = JSON::Validator.fully_validate(schema,data,:errors_as_objects => true)
assert_equal 2, errors.length
assert_equal '#/x', errors[0][:fragment]
assert_equal 'Required', errors[0][:failed_attribute]
assert_equal '#/x/e', errors[1][:fragment]
assert_equal 'TypeV4', errors[1][:failed_attribute]
end
def test_full_validation_with_nested_required_propertiesin_array
schema = {
"type" => "object",
"required" => ["x"],
"properties" => {
"x" => {
"type" => "array",
"items" => {
"type" => "object",
"required" => ["a", "b"],
"properties" => {
"a" => {"type"=>"integer"},
"b" => {"type"=>"integer"},
"c" => {"type"=>"integer"},
"d" => {"type"=>"integer"},
"e" => {"type"=>"integer"},
}
}
}
}
}
missing_b= {"a"=>5}
e_is_wrong_type= {"a"=>5,"b"=>5,"e"=>"what?"}
data = {"x" => [missing_b, e_is_wrong_type]}
errors = JSON::Validator.fully_validate(schema,data,:errors_as_objects => true)
assert_equal 2, errors.length
assert_equal '#/x/0', errors[0][:fragment]
assert_equal 'Required', errors[0][:failed_attribute]
assert_equal '#/x/1/e', errors[1][:fragment]
assert_equal 'TypeV4', errors[1][:failed_attribute]
end
end
ruby-json-schema-2.8.1/test/initialize_data_test.rb 0000664 0000000 0000000 00000011174 13411675645 0022425 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class InitializeDataTest < Minitest::Test
def test_parse_character_string
schema = {'type' => 'string'}
data = 'hello world'
assert(JSON::Validator.validate(schema, data))
assert(JSON::Validator.validate(schema, data, :parse_data => false))
assert_raises(JSON::Schema::JsonParseError) do
JSON::Validator.validate(schema, data, :json => true)
end
assert_raises(JSON::Schema::JsonLoadError) { JSON::Validator.validate(schema, data, :uri => true) }
end
def test_parse_integer_string
schema = {'type' => 'integer'}
data = '42'
assert(JSON::Validator.validate(schema, data))
refute(JSON::Validator.validate(schema, data, :parse_data => false))
assert(JSON::Validator.validate(schema, data, :json => true))
assert_raises(JSON::Schema::JsonLoadError) { JSON::Validator.validate(schema, data, :uri => true) }
end
def test_parse_hash_string
schema = { 'type' => 'object', 'properties' => { 'a' => { 'type' => 'string' } } }
data = '{"a": "b"}'
assert(JSON::Validator.validate(schema, data))
refute(JSON::Validator.validate(schema, data, :parse_data => false))
assert(JSON::Validator.validate(schema, data, :json => true))
assert_raises(JSON::Schema::UriError) { JSON::Validator.validate(schema, data, :uri => true) }
end
def test_parse_json_string
schema = {'type' => 'string'}
data = '"hello world"'
assert(JSON::Validator.validate(schema, data))
assert(JSON::Validator.validate(schema, data, :parse_data => false))
assert(JSON::Validator.validate(schema, data, :json => true))
assert_raises(JSON::Schema::JsonLoadError) { JSON::Validator.validate(schema, data, :uri => true) }
end
def test_parse_plain_text_string
schema = {'type' => 'string'}
data = 'kapow'
assert(JSON::Validator.validate(schema, data))
assert(JSON::Validator.validate(schema, data, :parse_data => false))
assert_raises(JSON::Schema::JsonParseError) do
JSON::Validator.validate(schema, data, :json => true)
end
assert_raises(JSON::Schema::JsonLoadError) { JSON::Validator.validate(schema, data, :uri => true) }
end
def test_parse_valid_uri_string
schema = {'type' => 'string'}
data = 'http://foo.bar/'
stub_request(:get, "foo.bar").to_return(:body => '"hello world"', :status => 200)
assert(JSON::Validator.validate(schema, data))
assert(JSON::Validator.validate(schema, data, :parse_data => false))
assert_raises(JSON::Schema::JsonParseError) do
JSON::Validator.validate(schema, data, :json => true)
end
assert(JSON::Validator.validate(schema, data, :uri => true))
end
def test_parse_invalid_uri_string
schema = {'type' => 'string'}
data = 'http://foo.bar/'
stub_request(:get, "foo.bar").to_timeout
assert(JSON::Validator.validate(schema, data))
assert(JSON::Validator.validate(schema, data, :parse_data => false))
stub_request(:get, "foo.bar").to_return(:status => [500, "Internal Server Error"])
assert(JSON::Validator.validate(schema, data))
assert(JSON::Validator.validate(schema, data, :parse_data => false))
assert_raises(JSON::Schema::JsonParseError) do
JSON::Validator.validate(schema, data, :json => true)
end
assert_raises(JSON::Schema::JsonLoadError) { JSON::Validator.validate(schema, data, :uri => true) }
end
def test_parse_invalid_scheme_string
schema = {'type' => 'string'}
data = 'pick one: [1, 2, 3]'
assert(JSON::Validator.validate(schema, data))
assert(JSON::Validator.validate(schema, data, :parse_data => false))
assert_raises(JSON::Schema::JsonParseError) do
JSON::Validator.validate(schema, data, :json => true)
end
assert_raises(JSON::Schema::UriError) { JSON::Validator.validate(schema, data, :uri => true) }
end
def test_parse_integer
schema = {'type' => 'integer'}
data = 42
assert(JSON::Validator.validate(schema, data))
assert(JSON::Validator.validate(schema, data, :parse_data => false))
assert_raises(TypeError) { JSON::Validator.validate(schema, data, :json => true) }
assert_raises(TypeError) { JSON::Validator.validate(schema, data, :uri => true) }
end
def test_parse_hash
schema = { 'type' => 'object', 'properties' => { 'a' => { 'type' => 'string' } } }
data = { 'a' => 'b' }
assert(JSON::Validator.validate(schema, data))
assert(JSON::Validator.validate(schema, data, :parse_data => false))
assert_raises(TypeError) { JSON::Validator.validate(schema, data, :json => true) }
assert_raises(TypeError) { JSON::Validator.validate(schema, data, :uri => true) }
end
end
ruby-json-schema-2.8.1/test/list_option_test.rb 0000664 0000000 0000000 00000001147 13411675645 0021635 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class ListOptionTest < Minitest::Test
def test_list_option_reusing_schemas
schema_hash = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"type" => "object",
"properties" => { "a" => { "type" => "integer" } }
}
uri = Addressable::URI.parse('http://example.com/item')
schema = JSON::Schema.new(schema_hash, uri)
JSON::Validator.add_schema(schema)
data = {"a" => 1}
assert_valid uri.to_s, data, clear_cache: false
data = [{"a" => 1}]
assert_valid uri.to_s, data, :list => true
end
end
ruby-json-schema-2.8.1/test/load_ref_schema_test.rb 0000664 0000000 0000000 00000002206 13411675645 0022362 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class LoadRefSchemaTest < Minitest::Test
def load_other_schema
JSON::Validator.add_schema(JSON::Schema.new(
{
'$schema' => 'http://json-schema.org/draft-04/schema#',
'type' => 'object',
'properties' => {
"title" => {
"type" => "string"
}
}
},
Addressable::URI.parse("http://example.com/schema#")
))
end
def test_cached_schema
schema_url = "http://example.com/schema#"
schema = { "$ref" => schema_url }
data = {}
load_other_schema
_validator = JSON::Validator.new(schema, data)
assert JSON::Validator.schema_loaded?(schema_url)
end
def test_cached_schema_with_fragment
schema_url = "http://example.com/schema#"
schema = { "$ref" => "#{schema_url}/properties/title" }
data = {}
load_other_schema
_validator = JSON::Validator.new(schema, data)
assert JSON::Validator.schema_loaded?(schema_url)
end
def test_metaschema
schema = { "$ref" => "http://json-schema.org/draft-04/schema#" }
data = {}
assert_valid schema, data
end
end
ruby-json-schema-2.8.1/test/merge_missing_values_test.rb 0000664 0000000 0000000 00000003341 13411675645 0023477 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class MergeMissingValuesTest < Minitest::Test
def test_merge_missing_values_for_string
original = 'foo'
updated = 'foo'
JSON::Validator.merge_missing_values(updated, original)
assert_equal('foo', original)
end
def test_merge_missing_values_for_empty_array
original = []
updated = []
JSON::Validator.merge_missing_values(updated, original)
assert_equal([], original)
end
def test_merge_missing_values_for_empty_hash
original = {}
updated = {}
JSON::Validator.merge_missing_values(updated, original)
assert_equal({}, original)
end
def test_merge_missing_values_for_new_values
original = {:hello => 'world'}
updated = {'hello' => 'world', 'foo' => 'bar'}
JSON::Validator.merge_missing_values(updated, original)
assert_equal({:hello => 'world', 'foo' => 'bar'}, original)
end
def test_merge_missing_values_for_nested_array
original = [:hello, 'world', 1, 2, 3, {:foo => :bar, 'baz' => 'qux'}]
updated = ['hello', 'world', 1, 2, 3, {'foo' => 'bar', 'baz' => 'qux', 'this_is' => 'new'}]
JSON::Validator.merge_missing_values(updated, original)
assert_equal([:hello, 'world', 1, 2, 3, {:foo => :bar, 'baz' => 'qux', 'this_is' => 'new'}], original)
end
def test_merge_missing_values_for_nested_hash
original = {:hello => 'world', :foo => ['bar', :baz, {:uno => {:due => 3}}]}
updated = {'hello' => 'world', 'foo' => ['bar', 'baz', {'uno' => {'due' => 3, 'this_is' => 'new'}}], 'ack' => 'sed'}
JSON::Validator.merge_missing_values(updated, original)
assert_equal({:hello => 'world', :foo => ['bar', :baz, {:uno => {:due => 3, 'this_is' => 'new'}}], 'ack' => 'sed'}, original)
end
end
ruby-json-schema-2.8.1/test/min_items_test.rb 0000664 0000000 0000000 00000000624 13411675645 0021255 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class MinItemsTest < Minitest::Test
def test_minitems_nils
schema = {
"type" => "array",
"minItems" => 1,
"items" => { "type" => "object" }
}
errors = JSON::Validator.fully_validate(schema, [nil])
assert_equal(errors.length, 1)
assert(errors[0] !~ /minimum/)
assert(errors[0] =~ /null/)
end
end
ruby-json-schema-2.8.1/test/one_of_test.rb 0000664 0000000 0000000 00000005423 13411675645 0020540 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class OneOfTest < Minitest::Test
def test_one_of_links_schema
schema = schema_fixture_path('one_of_ref_links_schema.json')
data = data_fixture_path('one_of_ref_links_data.json')
assert_valid schema, data
end
def test_one_of_with_string_patterns
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"oneOf" => [
{
"properties" => {"a" => {"type" => "string", "pattern" => "foo"}},
},
{
"properties" => {"a" => {"type" => "string", "pattern" => "bar"}},
},
{
"properties" => {"a" => {"type" => "string", "pattern" => "baz"}},
}
]
}
assert_valid schema, { "a" => "foo" }
refute_valid schema, { "a" => "foobar" }
assert_valid schema, { "a" => "baz" }
refute_valid schema, { "a" => 5 }
end
def test_one_of_sub_errors
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"oneOf" => [
{
"properties" => {"a" => {"type" => "string", "pattern" => "foo"}},
},
{
"properties" => {"a" => {"type" => "string", "pattern" => "bar"}},
},
{
"properties" => {"a" => {"type" => "number", "minimum" => 10}},
}
]
}
errors = JSON::Validator.fully_validate(schema, { "a" => 5 }, :errors_as_objects => true)
nested_errors = errors[0][:errors]
assert_equal([:oneof_0,:oneof_1,:oneof_2], nested_errors.keys, 'should have nested errors for each allOf subschema')
assert_match(/the property '#\/a' of type Integer did not match the following type: string/i, nested_errors[:oneof_0][0][:message])
assert_match(/the property '#\/a' did not have a minimum value of 10, inclusively/i, nested_errors[:oneof_2][0][:message])
end
def test_one_of_sub_errors_message
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"oneOf" => [
{
"properties" => {"a" => {"type" => "string", "pattern" => "foo"}},
},
{
"properties" => {"a" => {"type" => "string", "pattern" => "bar"}},
},
{
"properties" => {"a" => {"type" => "number", "minimum" => 10}},
}
]
}
errors = JSON::Validator.fully_validate(schema, { "a" => 5 })
expected_message = """The property '#/' of type object did not match any of the required schemas. The schema specific errors were:
- oneOf #0:
- The property '#/a' of type integer did not match the following type: string
- oneOf #1:
- The property '#/a' of type integer did not match the following type: string
- oneOf #2:
- The property '#/a' did not have a minimum value of 10, inclusively"""
assert_equal(expected_message, errors[0])
end
end
ruby-json-schema-2.8.1/test/relative_definition_test.rb 0000664 0000000 0000000 00000001065 13411675645 0023314 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class RelativeDefinitionTest < Minitest::Test
def test_definition_schema
assert_valid schema_fixture_path('definition_schema.json'), {"a" => 5}
end
def test_definition_schema_with_special_characters
assert_valid schema_fixture_path('definition_schema_with_special_characters.json'), {"a" => 5}
end
def test_relative_definition
schema = schema_fixture_path('relative_definition_schema.json')
assert_valid schema, {"a" => 5}
refute_valid schema, {"a" => "foo"}
end
end
ruby-json-schema-2.8.1/test/ruby_schema_test.rb 0000664 0000000 0000000 00000002410 13411675645 0021565 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class RubySchemaTest < Minitest::Test
def test_string_keys
schema = {
"type" => 'object',
"required" => ["a"],
"properties" => {
"a" => {"type" => "integer", "default" => 42},
"b" => {"type" => "integer"}
}
}
assert_valid schema, { "a" => 5 }
end
def test_symbol_keys
schema = {
:type => 'object',
:required => ["a"],
:properties => {
:a => {:type => "integer", :default => 42},
:b => {:type => "integer"}
}
}
assert_valid schema, { :a => 5 }
end
def test_symbol_keys_in_hash_within_array
schema = {
:type => 'object',
:properties => {
:a => {
:type => "array",
:items => [
{
:properties => {
:b => {
:type => "integer"
}
}
}
]
}
}
}
data = {
:a => [
{
:b => 1
}
]
}
assert_valid schema, data, :validate_schema => true
end
def test_schema_of_unrecognized_type
assert_raises JSON::Schema::SchemaParseError do
JSON::Validator.validate(Object.new, {})
end
end
end
ruby-json-schema-2.8.1/test/schema_reader_test.rb 0000664 0000000 0000000 00000004650 13411675645 0022056 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class SchemaReaderTest < Minitest::Test
ADDRESS_SCHEMA_URI = 'http://json-schema.org/address'
ADDRESS_SCHEMA_PATH = File.expand_path('../schemas/address_microformat.json', __FILE__)
def stub_address_request(body = File.read(ADDRESS_SCHEMA_PATH))
stub_request(:get, ADDRESS_SCHEMA_URI).
to_return(:body => body, :status => 200)
end
def test_accept_all_uris
stub_address_request
reader = JSON::Schema::Reader.new
schema = reader.read(ADDRESS_SCHEMA_URI)
assert_equal schema.uri, Addressable::URI.parse("#{ADDRESS_SCHEMA_URI}#")
end
def test_accept_all_files
reader = JSON::Schema::Reader.new
schema = reader.read(ADDRESS_SCHEMA_PATH)
assert_equal schema.uri, Addressable::URI.convert_path(ADDRESS_SCHEMA_PATH + '#')
end
def test_refuse_all_uris
reader = JSON::Schema::Reader.new(:accept_uri => false)
refute reader.accept_uri?(Addressable::URI.parse('http://foo.com'))
end
def test_refuse_all_files
reader = JSON::Schema::Reader.new(:accept_file => false)
refute reader.accept_file?(Pathname.new('/foo/bar/baz'))
end
def test_accept_uri_proc
reader = JSON::Schema::Reader.new(
:accept_uri => proc { |uri| uri.host == 'json-schema.org' }
)
assert reader.accept_uri?(Addressable::URI.parse('http://json-schema.org/address'))
refute reader.accept_uri?(Addressable::URI.parse('http://sub.json-schema.org/address'))
end
def test_accept_file_proc
test_root = Pathname.new(__FILE__).expand_path.dirname
reader = JSON::Schema::Reader.new(
:accept_file => proc { |path| path.to_s.start_with?(test_root.to_s) }
)
assert reader.accept_file?(test_root.join('anything.json'))
refute reader.accept_file?(test_root.join('..', 'anything.json'))
end
def test_file_scheme
reader = JSON::Schema::Reader.new(:accept_uri => true, :accept_file => false)
error = assert_raises(JSON::Schema::ReadRefused) do
reader.read('file://' + ADDRESS_SCHEMA_PATH)
end
assert_equal(:file, error.type)
assert_equal(ADDRESS_SCHEMA_PATH, error.location)
assert_equal("Read of file at #{ADDRESS_SCHEMA_PATH} refused", error.message)
end
def test_parse_error
stub_address_request('this is totally not valid JSON!')
reader = JSON::Schema::Reader.new
assert_raises(JSON::Schema::JsonParseError) do
reader.read(ADDRESS_SCHEMA_URI)
end
end
end
ruby-json-schema-2.8.1/test/schema_validation_test.rb 0000664 0000000 0000000 00000011013 13411675645 0022735 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
require 'tmpdir'
class SchemaValidationTest < Minitest::Test
def valid_schema_v3
{
"$schema" => "http://json-schema.org/draft-03/schema#",
"type" => "object",
"properties" => {
"b" => {
"required" => true
}
}
}
end
def invalid_schema_v3
{
"$schema" => "http://json-schema.org/draft-03/schema#",
"type" => "object",
"properties" => {
"b" => {
"required" => "true"
}
}
}
end
def valid_schema_v4
{
"$schema" => "http://json-schema.org/draft-04/schema#",
"type" => "object",
"required" => ["b"],
"properties" => {
}
}
end
def invalid_schema_v4
{
"$schema" => "http://json-schema.org/draft-04/schema#",
"type" => "object",
"required" => "b",
"properties" => {
}
}
end
def symbolized_schema
{
:type => :object,
:required => [
:id,
:name,
:real_name,
:role,
:website,
:biography,
:created_at,
:demographic
],
:properties => {
:id => {
:type => [
:integer
]
},
:name => {
:type => [
:string
]
},
:real_name => {
:type => [
:string
]
},
:role => {
:type => [
:string
]
},
:website => {
:type => [
:string,
:null
]
},
:created_at => {
:type => [
:string
]
},
:biography => {
:type => [
:string,
:null
]
}
},
:relationships => {
:demographic => {
:type => :object,
:required => [
:id,
:gender
],
:properties => {
:id => {
:type => [
:integer
]
},
:gender => {
:type => [
:string
]
}
}
}
}
}
end
def test_draft03_validation
data = {"b" => {"a" => 5}}
assert(JSON::Validator.validate(valid_schema_v3,data,:validate_schema => true, :version => :draft3))
assert(!JSON::Validator.validate(invalid_schema_v3,data,:validate_schema => true, :version => :draft3))
end
def test_validate_just_schema_draft03
errors = JSON::Validator.fully_validate_schema(valid_schema_v3, :version => :draft3)
assert_equal [], errors
errors = JSON::Validator.fully_validate_schema(invalid_schema_v3, :version => :draft3)
assert_equal 1, errors.size
assert_match(/the property .*required.*did not match/i, errors.first)
end
def test_draft04_validation
data = {"b" => {"a" => 5}}
assert(JSON::Validator.validate(valid_schema_v4,data,:validate_schema => true, :version => :draft4))
assert(!JSON::Validator.validate(invalid_schema_v4,data,:validate_schema => true, :version => :draft4))
end
def test_validate_just_schema_draft04
errors = JSON::Validator.fully_validate_schema(valid_schema_v4, :version => :draft4)
assert_equal [], errors
errors = JSON::Validator.fully_validate_schema(invalid_schema_v4, :version => :draft4)
assert_equal 1, errors.size
assert_match(/the property .*required.*did not match/i, errors.first)
end
def test_validate_schema_3_without_version_option
data = {"b" => {"a" => 5}}
assert(JSON::Validator.validate(valid_schema_v3,data,:validate_schema => true))
assert(!JSON::Validator.validate(invalid_schema_v3,data,:validate_schema => true))
end
def test_schema_validation_from_different_directory
Dir.mktmpdir do |tmpdir|
Dir.chdir(tmpdir) do
data = {"b" => {"a" => 5}}
assert(JSON::Validator.validate(valid_schema_v4,data,:validate_schema => true, :version => :draft4))
assert(!JSON::Validator.validate(invalid_schema_v4,data,:validate_schema => true, :version => :draft4))
end
end
end
def test_validate_schema_with_symbol_keys
data = {
"created_at" => "2014-01-25T00:58:33-08:00",
"id" => 8517194300913402149003,
"name" => "chelsey",
"real_name" => "Mekhi Hegmann",
"website" => nil,
"role" => "user",
"biography" => nil,
"demographic" => nil
}
assert(JSON::Validator.validate!(symbolized_schema, data, :validate_schema => true))
end
end
ruby-json-schema-2.8.1/test/schemas/ 0000775 0000000 0000000 00000000000 13411675645 0017326 5 ustar 00root root 0000000 0000000 ruby-json-schema-2.8.1/test/schemas/address_microformat.json 0000664 0000000 0000000 00000001200 13411675645 0024241 0 ustar 00root root 0000000 0000000 {
"description": "An Address following the convention of http://microformats.org/wiki/hcard",
"type": "object",
"properties": {
"post-office-box": { "type": "string" },
"extended-address": { "type": "string" },
"street-address": { "type": "string" },
"locality":{ "type": "string" },
"region": { "type": "string" },
"postal-code": { "type": "string" },
"country-name": { "type": "string"}
},
"required": ["locality", "region", "country-name"],
"dependencies": {
"post-office-box": "street-address",
"extended-address": "street-address"
}
}
ruby-json-schema-2.8.1/test/schemas/all_of_ref_base_schema.json 0000664 0000000 0000000 00000000121 13411675645 0024615 0 ustar 00root root 0000000 0000000 {
"type": "object",
"properties" : {
"name" : { "type": "integer" }
}
}
ruby-json-schema-2.8.1/test/schemas/all_of_ref_schema.json 0000664 0000000 0000000 00000000220 13411675645 0023623 0 ustar 00root root 0000000 0000000 { "$schema" : "http://json-schema.org/draft-04/schema#",
"type" : "object",
"allOf" :
[ { "$ref" : "all_of_ref_base_schema.json" }
]
}
ruby-json-schema-2.8.1/test/schemas/any_of_ref_jane_schema.json 0000664 0000000 0000000 00000000143 13411675645 0024643 0 ustar 00root root 0000000 0000000 { "$schema" : "http://json-schema.org/draft-04/schema#"
, "type" : "string"
, "pattern" : "jane"
}
ruby-json-schema-2.8.1/test/schemas/any_of_ref_jimmy_schema.json 0000664 0000000 0000000 00000000144 13411675645 0025054 0 ustar 00root root 0000000 0000000 { "$schema" : "http://json-schema.org/draft-04/schema#"
, "type" : "string"
, "pattern" : "jimmy"
}
ruby-json-schema-2.8.1/test/schemas/any_of_ref_john_schema.json 0000664 0000000 0000000 00000000143 13411675645 0024664 0 ustar 00root root 0000000 0000000 { "$schema" : "http://json-schema.org/draft-04/schema#"
, "type" : "string"
, "pattern" : "john"
}
ruby-json-schema-2.8.1/test/schemas/any_of_ref_schema.json 0000664 0000000 0000000 00000000542 13411675645 0023651 0 ustar 00root root 0000000 0000000 { "$schema" : "http://json-schema.org/draft-04/schema#"
, "type" : "object"
, "properties" :
{ "names" :
{ "type" : "array"
, "items" :
{ "anyOf" :
[ { "$ref" : "any_of_ref_john_schema.json" }
, { "$ref" : "any_of_ref_jane_schema.json" }
, { "$ref" : "any_of_ref_jimmy_schema.json" }
]
}
}
}
}
ruby-json-schema-2.8.1/test/schemas/definition_schema.json 0000664 0000000 0000000 00000000407 13411675645 0023672 0 ustar 00root root 0000000 0000000 {
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "schema with definition",
"type": "object",
"properties": {
"a": {
"$ref": "#/definitions/foo"
}
},
"definitions": {
"foo": {
"type": "integer"
}
}
}
ruby-json-schema-2.8.1/test/schemas/definition_schema_with_special_characters.json 0000664 0000000 0000000 00000000344 13411675645 0030624 0 ustar 00root root 0000000 0000000 {
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"a": {
"$ref": "#/definitions/foo:bar"
}
},
"definitions": {
"foo:bar": {
"type": "integer"
}
}
}
ruby-json-schema-2.8.1/test/schemas/extends_and_additionalProperties_false_schema.json 0000664 0000000 0000000 00000001100 13411675645 0031444 0 ustar 00root root 0000000 0000000 {
"type": "object",
"extends": {"$ref":"inner_schema.json#"},
"properties": {
"outerA": {
"description": "blah",
"additionalProperties": false,
"properties": {
"outerA1": {
"type":"boolean"
}
}
},
"outerB": {
"type": "array",
"minItems": 1,
"maxItems": 50,
"items": {
"extends": {"$ref":"inner_schema.json#"},
"additionalProperties": false
}
},
"outerC": {
"description": "blah",
"type":"boolean"
}
},
"additionalProperties": false
}
ruby-json-schema-2.8.1/test/schemas/extends_and_patternProperties_schema.json 0000664 0000000 0000000 00000001046 13411675645 0027650 0 ustar 00root root 0000000 0000000 {
"type": "object",
"extends": {"$ref":"inner_schema.json#"},
"patternProperties": {
"outerA": {
"description": "blah",
"additionalProperties": false,
"properties": {
"outerA1": {
"type":"boolean"
}
}
},
"outerB": {
"type": "array",
"minItems": 1,
"maxItems": 50,
"items": {
"extends": {"$ref":"inner_schema.json#"},
"additionalProperties": false
}
},
"outerC": {
"description": "blah",
"type":"boolean"
}
}
}
ruby-json-schema-2.8.1/test/schemas/good_schema_1.json 0000664 0000000 0000000 00000000160 13411675645 0022706 0 ustar 00root root 0000000 0000000 {
"type" : "object",
"properties" : {
"a" : {
"type" : "integer"
}
},
"required": ["a"]
}
ruby-json-schema-2.8.1/test/schemas/good_schema_2.json 0000664 0000000 0000000 00000000173 13411675645 0022713 0 ustar 00root root 0000000 0000000 {
"type" : "object",
"properties" : {
"b" : {
"$ref" : "good_schema_1.json"
}
},
"required": ["b"]
}
ruby-json-schema-2.8.1/test/schemas/good_schema_extends1.json 0000664 0000000 0000000 00000000157 13411675645 0024307 0 ustar 00root root 0000000 0000000 {
"type" : "object",
"extends": {"$ref": "good_schema_1.json"},
"properties" : {
"c" : {
}
}
}
ruby-json-schema-2.8.1/test/schemas/good_schema_extends2.json 0000664 0000000 0000000 00000000235 13411675645 0024305 0 ustar 00root root 0000000 0000000 {
"type" : "object",
"extends": [
{"$ref": "good_schema_1.json"},
{"$ref": "good_schema_2.json"}
],
"properties" : {
"c" : {
}
}
}
ruby-json-schema-2.8.1/test/schemas/inner_schema.json 0000664 0000000 0000000 00000000417 13411675645 0022656 0 ustar 00root root 0000000 0000000 {
"type": "object",
"properties": {
"innerA": {
"description": "blah",
"type":"boolean"
},
"innerB": {
"description": "blah",
"type":"boolean"
},
"innerC": {
"description": "blah",
"type": "boolean"
}
}
}
ruby-json-schema-2.8.1/test/schemas/one_of_ref_links_schema.json 0000664 0000000 0000000 00000000465 13411675645 0025047 0 ustar 00root root 0000000 0000000 { "$schema": "http://json-schema.org/draft-04/schema#"
, "type": "object"
, "properties":
{ "links" :
{ "type" : "array"
, "items" :
{ "type" : "object"
, "oneOf" :
[ { "$ref" : "self_link_schema.json"}
, { "$ref" : "up_link_schema.json" }
]
}
}
}
}
ruby-json-schema-2.8.1/test/schemas/ref john with spaces schema.json 0000664 0000000 0000000 00000000306 13411675645 0025327 0 ustar 00root root 0000000 0000000 {
"$schema" : "http://json-schema.org/draft-04/schema#",
"type" : "object",
"required" : ["first"],
"properties": {
"first": {
"type": "string",
"enum": ["john"]
}
}
}
ruby-json-schema-2.8.1/test/schemas/relative_definition_schema.json 0000664 0000000 0000000 00000000232 13411675645 0025561 0 ustar 00root root 0000000 0000000 {
"$schema": "http://json-schema.org/draft-04/schema#",
"properties": {
"a": {
"$ref": "definition_schema.json#/definitions/foo"
}
}
} ruby-json-schema-2.8.1/test/schemas/self_link_schema.json 0000664 0000000 0000000 00000000421 13411675645 0023504 0 ustar 00root root 0000000 0000000 { "$schema": "http://json-schema.org/draft-04/schema#"
, "type": "object"
, "properties" :
{ "rel" :
{ "type" : "array"
, "items" :
[ { "type" : "string"
, "pattern" : "self"
}
]
}
, "href" :
{ "type" : "string"
}
}
}
ruby-json-schema-2.8.1/test/schemas/up_link_schema.json 0000664 0000000 0000000 00000000417 13411675645 0023204 0 ustar 00root root 0000000 0000000 { "$schema": "http://json-schema.org/draft-04/schema#"
, "type": "object"
, "properties" :
{ "rel" :
{ "type" : "array"
, "items" :
[ { "type" : "string"
, "pattern" : "up"
}
]
}
, "href" :
{ "type" : "string"
}
}
}
ruby-json-schema-2.8.1/test/stringify_test.rb 0000664 0000000 0000000 00000002407 13411675645 0021310 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class StringifyTest < Minitest::Test
def test_stringify_on_hash
hash = {
:a => 'foo',
'b' => :bar
}
assert_equal({'a' => 'foo', 'b' => 'bar'}, JSON::Schema.stringify(hash), 'symbol keys should be converted to strings')
end
def test_stringify_on_array
array = [
:a,
'b'
]
assert_equal(['a', 'b'], JSON::Schema.stringify(array), 'symbols in an array should be converted to strings')
end
def test_stringify_on_hash_of_arrays
hash = {
:a => [:foo],
'b' => :bar
}
assert_equal({'a' => ['foo'], 'b' => 'bar'}, JSON::Schema.stringify(hash), 'symbols in a nested array should be converted to strings')
end
def test_stringify_on_array_of_hashes
array = [
:a,
{
:b => :bar
}
]
assert_equal(['a', {'b' => 'bar'}], JSON::Schema.stringify(array), 'symbols keys in a nested hash should be converted to strings')
end
def test_stringify_on_hash_of_hashes
hash = {
:a => {
:b => {
:foo => :bar
}
}
}
assert_equal({'a' => {'b' => {'foo' => 'bar'} } }, JSON::Schema.stringify(hash), 'symbols in a nested hash of hashes should be converted to strings')
end
end
ruby-json-schema-2.8.1/test/support/ 0000775 0000000 0000000 00000000000 13411675645 0017417 5 ustar 00root root 0000000 0000000 ruby-json-schema-2.8.1/test/support/array_validation.rb 0000664 0000000 0000000 00000005164 13411675645 0023302 0 ustar 00root root 0000000 0000000 module ArrayValidation
module ItemsTests
def test_items_single_schema
schema = { 'items' => { 'type' => 'string' } }
assert_valid schema, []
assert_valid schema, ['a']
assert_valid schema, ['a', 'b']
refute_valid schema, [1]
refute_valid schema, ['a', 1]
# other types are disregarded
assert_valid schema, {'a' => 'foo'}
end
def test_items_multiple_schemas
schema = {
'items' => [
{ 'type' => 'string' },
{ 'type' => 'integer' }
]
}
assert_valid schema, ['b', 1]
assert_valid schema, ['b', 1, nil]
refute_valid schema, [1, 'b']
assert_valid schema, []
assert_valid schema, ['b']
assert_valid schema, ['b', 1, 25]
end
def test_minitems
schema = { 'minItems' => 1 }
assert_valid schema, [1]
assert_valid schema, [1, 2]
refute_valid schema, []
# other types are disregarded
assert_valid schema, 5
end
def test_maxitems
schema = { 'maxItems' => 1 }
assert_valid schema, []
assert_valid schema, [1]
refute_valid schema, [1, 2]
# other types are disregarded
assert_valid schema, 5
end
end
module AdditionalItemsTests
def test_additional_items_false
schema = {
'items' => [
{ 'type' => 'integer' },
{ 'type' => 'string' }
],
'additionalItems' => false
}
assert_valid schema, [1, 'string']
assert_valid schema, [1]
assert_valid schema, []
refute_valid schema, [1, 'string', 2]
refute_valid schema, ['string', 1]
end
def test_additional_items_schema
schema = {
'items' => [
{ 'type' => 'integer' },
{ 'type' => 'string' }
],
'additionalItems' => { 'type' => 'integer' }
}
assert_valid schema, [1, 'string']
assert_valid schema, [1, 'string', 2]
refute_valid schema, [1, 'string', 'string']
end
end
module UniqueItemsTests
def test_unique_items
schema = { 'uniqueItems' => true }
assert_valid schema, [nil, 5]
refute_valid schema, [nil, nil]
assert_valid schema, [true, false]
refute_valid schema, [true, true]
assert_valid schema, [4, 4.1]
refute_valid schema, [4, 4]
assert_valid schema, ['a', 'ab']
refute_valid schema, ['a', 'a']
assert_valid schema, [[1], [2]]
refute_valid schema, [[1], [1]]
assert_valid schema, [{'b' => 1}, {'c' => 2}]
assert_valid schema, [{'b' => 1}, {'c' => 1}]
refute_valid schema, [{'b' => 1}, {'b' => 1}]
end
end
end
ruby-json-schema-2.8.1/test/support/enum_validation.rb 0000664 0000000 0000000 00000004752 13411675645 0023132 0 ustar 00root root 0000000 0000000 module EnumValidation
module V1_V2
def test_enum_optional
schema = {
"properties" => {
"a" => {"enum" => [1,'boo',[1,2,3],{"a" => "b"}], "optional" => true}
}
}
data = {}
assert_valid schema, data
end
end
module V3_V4
def test_enum_optional
schema = {
"properties" => {
"a" => {"enum" => [1,'boo',[1,2,3],{"a" => "b"}]}
}
}
data = {}
assert_valid schema, data
end
end
module General
def test_enum_general
schema = {
"properties" => {
"a" => {"enum" => [1,'boo',[1,2,3],{"a" => "b"}]}
}
}
data = { "a" => 1 }
assert_valid schema, data
data["a"] = 'boo'
assert_valid schema, data
data["a"] = [1,2,3]
assert_valid schema, data
data["a"] = {"a" => "b"}
assert_valid schema, data
data["a"] = 'taco'
refute_valid schema, data
end
def test_enum_number_integer_includes_float
schema = {
"properties" => {
"a" => {
"type" => "number",
"enum" => [0, 1, 2]
}
}
}
data = { "a" => 0 }
assert_valid schema, data
data["a"] = 0.0
assert_valid schema, data
data["a"] = 1
assert_valid schema, data
data["a"] = 1.0
assert_valid schema, data
end
def test_enum_number_float_includes_integer
schema = {
"properties" => {
"a" => {
"type" => "number",
"enum" => [0.0, 1.0, 2.0]
}
}
}
data = { "a" => 0.0 }
assert_valid schema, data
data["a"] = 0
assert_valid schema, data
data["a"] = 1.0
assert_valid schema, data
data["a"] = 1
assert_valid schema, data
end
def test_enum_integer_excludes_float
schema = {
"properties" => {
"a" => {
"type" => "integer",
"enum" => [0, 1, 2]
}
}
}
data = { "a" => 0 }
assert_valid schema, data
data["a"] = 0.0
refute_valid schema, data
data["a"] = 1
assert_valid schema, data
data["a"] = 1.0
refute_valid schema, data
end
def test_enum_with_schema_validation
schema = {
"properties" => {
"a" => {"enum" => [1,'boo',[1,2,3],{"a" => "b"}]}
}
}
data = { "a" => 1 }
assert_valid(schema, data, :validate_schema => true)
end
end
end
ruby-json-schema-2.8.1/test/support/number_validation.rb 0000664 0000000 0000000 00000003433 13411675645 0023451 0 ustar 00root root 0000000 0000000 module NumberValidation
module MinMaxTests
def test_minimum
schema = {
'properties' => {
'a' => { 'minimum' => 5 }
}
}
assert_valid schema, {'a' => 5}
assert_valid schema, {'a' => 6}
refute_valid schema, {'a' => 4}
refute_valid schema, {'a' => 4.99999}
# other types are disregarded
assert_valid schema, {'a' => 'str'}
end
def test_exclusive_minimum
schema = {
'properties' => {
'a' => { 'minimum' => 5 }.merge(exclusive_minimum)
}
}
assert_valid schema, {'a' => 6}
assert_valid schema, {'a' => 5.0001}
refute_valid schema, {'a' => 5}
end
def test_maximum
schema = {
'properties' => {
'a' => { 'maximum' => 5 }
}
}
assert_valid schema, {'a' => 4}
assert_valid schema, {'a' => 5}
refute_valid schema, {'a' => 6}
refute_valid schema, {'a' => 5.0001}
end
def test_exclusive_maximum
schema = {
'properties' => {
'a' => { 'maximum' => 5 }.merge(exclusive_maximum)
}
}
assert_valid schema, {'a' => 4}
assert_valid schema, {'a' => 4.99999}
refute_valid schema, {'a' => 5}
end
end
# draft3 introduced `divisibleBy`, renamed to `multipleOf` in draft4.
# Favor the newer name, but the behavior should be identical.
module MultipleOfTests
def multiple_of
'multipleOf'
end
def test_multiple_of
schema = {
'properties' => {
'a' => { multiple_of => 1.1 }
}
}
assert_valid schema, {'a' => 0}
assert_valid schema, {'a' => 2.2}
refute_valid schema, {'a' => 3.4}
# other types are disregarded
assert_valid schema, {'a' => 'hi'}
end
end
end
ruby-json-schema-2.8.1/test/support/object_validation.rb 0000664 0000000 0000000 00000003456 13411675645 0023434 0 ustar 00root root 0000000 0000000 module ObjectValidation
module AdditionalPropertiesTests
def test_additional_properties_false
schema = {
'properties' => {
'a' => { 'type' => 'integer' }
},
'additionalProperties' => false
}
assert_valid schema, {'a' => 1}
refute_valid schema, {'a' => 1, 'b' => 2}
end
def test_additional_properties_schema
schema = {
'properties' => {
'a' => { 'type' => 'integer' }
},
'additionalProperties' => { 'type' => 'string' }
}
assert_valid schema, {'a' => 1}
assert_valid schema, {'a' => 1, 'b' => 'hi'}
refute_valid schema, {'a' => 1, 'b' => 2}
end
end
module PatternPropertiesTests
def test_pattern_properties
schema = {
'patternProperties' => {
"\\d+ taco" => { 'type' => 'integer' }
}
}
assert_valid schema, {'1 taco' => 1, '20 taco' => 20}
assert_valid schema, {'foo' => true, '1 taco' => 1}
refute_valid schema, {'1 taco' => 'yum'}
end
def test_pattern_properties_additional_properties_false
schema = {
'patternProperties' => {
"\\d+ taco" => { 'type' => 'integer' }
},
'additionalProperties' => false
}
assert_valid schema, {'1 taco' => 1}
refute_valid schema, {'1 taco' => 'yum'}
refute_valid schema, {'1 taco' => 1, 'foo' => true}
end
def test_pattern_properties_additional_properties_schema
schema = {
'patternProperties' => {
"\\d+ taco" => { 'type' => 'integer' }
},
'additionalProperties' => { 'type' => 'string' }
}
assert_valid schema, {'1 taco' => 1}
assert_valid schema, {'1 taco' => 1, 'foo' => 'bar'}
refute_valid schema, {'1 taco' => 1, 'foo' => 2}
end
end
end
ruby-json-schema-2.8.1/test/support/strict_validation.rb 0000664 0000000 0000000 00000005365 13411675645 0023477 0 ustar 00root root 0000000 0000000 module StrictValidation
def test_strict_properties
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"properties" => {
"a" => {"type" => "string"},
"b" => {"type" => "string"}
}
}
data = {"a" => "a"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"b" => "b"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b"}
assert(JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b", "c" => "c"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
end
def test_strict_error_message
schema = { :type => 'object', :properties => { :a => { :type => 'string' } } }
data = { :a => 'abc', :b => 'abc' }
errors = JSON::Validator.fully_validate(schema,data,:strict => true)
assert_match("The property '#/' contained undefined properties: 'b' in schema", errors[0])
end
def test_strict_properties_additional_props
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"properties" => {
"a" => {"type" => "string"},
"b" => {"type" => "string"}
},
"additionalProperties" => {"type" => "integer"}
}
data = {"a" => "a"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"b" => "b"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b"}
assert(JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b", "c" => "c"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b", "c" => 3}
assert(JSON::Validator.validate(schema,data,:strict => true))
end
def test_strict_properties_pattern_props
schema = {
"properties" => {
"a" => {"type" => "string"},
"b" => {"type" => "string"}
},
"patternProperties" => {"\\d+ taco" => {"type" => "integer"}}
}
data = {"a" => "a"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"b" => "b"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b"}
assert(JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b", "c" => "c"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b", "c" => 3}
assert(!JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b", "23 taco" => 3}
assert(JSON::Validator.validate(schema,data,:strict => true))
data = {"a" => "a", "b" => "b", "23 taco" => "cheese"}
assert(!JSON::Validator.validate(schema,data,:strict => true))
end
end
ruby-json-schema-2.8.1/test/support/string_validation.rb 0000664 0000000 0000000 00000010025 13411675645 0023462 0 ustar 00root root 0000000 0000000 module StringValidation
module ValueTests
def test_minlength
schema = {
'properties' => {
'a' => { 'minLength' => 1 }
}
}
assert_valid schema, {'a' => 't'}
refute_valid schema, {'a' => ''}
# other types are disregarded
assert_valid schema, {'a' => 5}
end
def test_maxlength
schema = {
'properties' => {
'a' => { 'maxLength' => 2 }
}
}
assert_valid schema, {'a' => 'tt'}
assert_valid schema, {'a' => ''}
refute_valid schema, {'a' => 'ttt'}
# other types are disregarded
assert_valid schema, {'a' => 5}
end
def test_pattern
schema = {
'properties' => {
'a' => { 'pattern' => "\\d+ taco" }
}
}
assert_valid schema, {'a' => '156 taco bell'}
refute_valid schema, {'a' => 'x taco'}
# other types are disregarded
assert_valid schema, {'a' => 5}
end
end
module FormatTests
# Draft1..3 use the format name `ip-address`; draft4 changed it to `ipv4`.
def ipv4_format
'ip-address'
end
def test_format_unknown
schema = {
'properties' => {
'a' => { 'format' => 'unknown' }
}
}
assert_valid schema, {'a' => 'absolutely anything!'}
assert_valid schema, {'a' => ''}
end
def test_format_union
schema = {
'properties' => {
'a' => {
'type' => ['string', 'null'],
'format' => 'date-time'
}
}
}
assert_valid schema, {'a' => nil}
refute_valid schema, {'a' => 'wrong'}
end
def test_format_ipv4
schema = {
'properties' => {
'a' => { 'format' => ipv4_format }
}
}
assert_valid schema, {"a" => "1.1.1.1"}
refute_valid schema, {"a" => "1.1.1"}
refute_valid schema, {"a" => "1.1.1.300"}
refute_valid schema, {"a" => "1.1.1"}
refute_valid schema, {"a" => "1.1.1.1b"}
# other types are disregarded
assert_valid schema, {'a' => 5}
end
def test_format_ipv6
schema = {
'properties' => {
'a' => { 'format' => 'ipv6' }
}
}
assert_valid schema, {"a" => "1111:2222:8888:9999:aaaa:cccc:eeee:ffff"}
assert_valid schema, {"a" => "1111:0:8888:0:0:0:eeee:ffff"}
assert_valid schema, {"a" => "1111:2222:8888::eeee:ffff"}
assert_valid schema, {"a" => "::1"}
refute_valid schema, {"a" => "1111:2222:8888:99999:aaaa:cccc:eeee:ffff"}
refute_valid schema, {"a" => "1111:2222:8888:9999:aaaa:cccc:eeee:gggg"}
refute_valid schema, {"a" => "1111:2222::9999::cccc:eeee:ffff"}
refute_valid schema, {"a" => "1111:2222:8888:9999:aaaa:cccc:eeee:ffff:bbbb"}
refute_valid schema, {"a" => "42"}
refute_valid schema, {"a" => "b"}
end
end
# Draft1..3 explicitly support `date`, `time` formats in addition to
# the `date-time` format.
module DateAndTimeFormatTests
def test_format_time
schema = {
'properties' => {
'a' => { 'format' => 'time' }
}
}
assert_valid schema, {"a" => "12:00:00"}
refute_valid schema, {"a" => "12:00"}
refute_valid schema, {"a" => "12:00:60"}
refute_valid schema, {"a" => "12:60:00"}
refute_valid schema, {"a" => "24:00:00"}
refute_valid schema, {"a" => "0:00:00"}
refute_valid schema, {"a" => "-12:00:00"}
refute_valid schema, {"a" => "12:00:00b"}
assert_valid schema, {"a" => "12:00:00"}
refute_valid schema, {"a" => "12:00:00\nabc"}
end
def test_format_date
schema = {
'properties' => {
'a' => { 'format' => 'date' }
}
}
assert_valid schema, {"a" => "2010-01-01"}
refute_valid schema, {"a" => "2010-01-32"}
refute_valid schema, {"a" => "n2010-01-01"}
refute_valid schema, {"a" => "2010-1-01"}
refute_valid schema, {"a" => "2010-01-1"}
refute_valid schema, {"a" => "2010-01-01n"}
refute_valid schema, {"a" => "2010-01-01\nabc"}
end
end
end
ruby-json-schema-2.8.1/test/support/test_helper.rb 0000664 0000000 0000000 00000002541 13411675645 0022264 0 ustar 00root root 0000000 0000000 if ENV['COVERAGE']
require 'simplecov'
SimpleCov.start do
add_filter '/test/'
end
end
require 'minitest/autorun'
require 'webmock/minitest'
$LOAD_PATH.unshift(File.expand_path('../../../lib', __FILE__))
require 'json-schema'
Dir[File.join(File.expand_path('../', __FILE__), '*.rb')].each do |support_file|
require support_file unless support_file == __FILE__
end
class Minitest::Test
def suppress_warnings
old_verbose = $VERBOSE
$VERBOSE = nil
begin
yield
ensure
$VERBOSE = old_verbose
end
end
def schema_fixture_path(filename)
File.join(File.dirname(__FILE__), '../schemas', filename)
end
def data_fixture_path(filename)
File.join(File.dirname(__FILE__), '../data', filename)
end
def assert_valid(schema, data, options = {}, msg = "#{data.inspect} should be valid for schema:\n#{schema.inspect}")
errors = validation_errors(schema, data, options)
assert_equal([], errors, msg)
end
def refute_valid(schema, data, options = {}, msg = "#{data.inspect} should be invalid for schema:\n#{schema.inspect}")
errors = validation_errors(schema, data, options)
refute_equal([], errors, msg)
end
def validation_errors(schema, data, options)
options = { :clear_cache => true, :validate_schema => true }.merge(options)
JSON::Validator.fully_validate(schema, data, options)
end
end
ruby-json-schema-2.8.1/test/support/test_suite_ignored_tests.yml 0000664 0000000 0000000 00000013337 13411675645 0025272 0 ustar 00root root 0000000 0000000 # These are test files which we know fail spectacularly, either because we
# don't support that functionality or because they require external
# dependencies. To allow finer-grained control over which tests to run,
# you can replace `:all` with an array containing the names of individual
# tests to skip.
draft3:
ref:
- ref overrides any sibling keywords/remote ref valid, maxItems ignored
optional:
jsregex: :all
format:
- validation of regular expressions/a regular expression with unclosed parens is invalid
- validation of e-mail addresses/an invalid e-mail address
- validation of URIs/an invalid URI
- validation of URIs/an invalid protocol-relative URI Reference
- validation of URIs/an invalid URI though valid URI reference
- validation of host names/a host name with a component too long
- validation of host names/a host name containing illegal characters
- validation of host names/a host name starting with an illegal character
- validation of CSS colors/an invalid CSS color code
- validation of CSS colors/an invalid CSS color name
- validation of CSS colors/a CSS color name containing invalid characters
draft4:
ref:
- ref overrides any sibling keywords/remote ref valid, maxItems ignored
- ref overrides any sibling keywords/ref valid, maxItems ignored
optional:
format:
- validation of URIs/an invalid URI
- validation of URIs/an invalid protocol-relative URI Reference
- validation of URIs/an invalid URI though valid URI reference
- validation of e-mail addresses/an invalid e-mail address
- validation of host names/a host name with a component too long
- validation of host names/a host name containing illegal characters
- validation of host names/a host name starting with an illegal character
ecmascript-regex:
- ECMA 262 regex non-compliance/ECMA 262 has no support for \Z anchor from .NET
bignum:
- float comparison with high precision on negative numbers/comparison works for very negative numbers
- float comparison with high precision/comparison works for high numbers
draft6:
allOf:
- allOf with boolean schemas, some false/any value is invalid
- allOf with boolean schemas, all false/any value is invalid
- allOf with boolean schemas, all true/any value is valid
anyOf:
- anyOf with boolean schemas, all false/any value is invalid
- anyOf with boolean schemas, all true/any value is valid
- anyOf with boolean schemas, some true/any value is valid
boolean_schema: :all
const: :all
contains: :all
dependencies:
- dependencies with boolean subschemas/empty object is valid
- dependencies with boolean subschemas/object with both properties is invalid
- dependencies with boolean subschemas/object with property having schema false is invalid
- dependencies with boolean subschemas/object with property having schema true is valid
- dependencies with empty array/empty object
- dependencies with empty array/object with one property
exclusiveMaximum: :all
exclusiveMinimum: :all
items:
- items with boolean schema (false)/any non-empty array is invalid
- items with boolean schema (false)/empty array is valid
- items with boolean schema (true)/any array is valid
- items with boolean schema (true)/empty array is valid
- items with boolean schemas/array with one item is valid
- items with boolean schemas/array with two items is invalid
- items with boolean schemas/empty array is valid
not: :all
oneOf:
- oneOf with boolean schemas, all false/any value is invalid
- oneOf with boolean schemas, all true/any value is invalid
- oneOf with boolean schemas, one true/any value is valid
- oneOf with boolean schemas, more than one true/any value is invalid
patternProperties:
- patternProperties with boolean schemas/object with property matching schema false is invalid
- patternProperties with boolean schemas/object with both properties is invalid
- patternProperties with boolean schemas/object with property matching schema true is valid
- patternProperties with boolean schemas/empty object is valid
properties:
- properties with boolean schema/only 'true' property present is valid
- properties with boolean schema/only 'false' property present is invalid
- properties with boolean schema/no property present is valid
- properties with boolean schema/both properties present is invalid
propertyNames: :all
ref:
- ref overrides any sibling keywords/remote ref valid, maxItems ignored
- ref overrides any sibling keywords/ref valid, maxItems ignored
- $ref to boolean schema true/any value is valid
- $ref to boolean schema false/any value is invalid
required:
- required with empty array/property not required
optional:
bignum:
- float comparison with high precision/comparison works for high numbers
- float comparison with high precision on negative numbers/comparison works for very negative numbers
format:
- validation of URIs/an invalid URI
- validation of URIs/an invalid protocol-relative URI Reference
- validation of URIs/an invalid URI though valid URI reference
- validation of e-mail addresses/an invalid e-mail address
- validation of host names/a host name with a component too long
- validation of host names/a host name containing illegal characters
- validation of host names/a host name starting with an illegal character
ecmascript-regex:
- ECMA 262 regex non-compliance/ECMA 262 has no support for \Z anchor from .NET
zeroTerminatedFloats:
- some languages do not distinguish between different types of numeric value/a float is not an integer even without fractional part
ruby-json-schema-2.8.1/test/support/type_validation.rb 0000664 0000000 0000000 00000004026 13411675645 0023141 0 ustar 00root root 0000000 0000000 module TypeValidation
# The draft4 schema refers to the JSON types as 'simple types';
# see draft4#/definitions/simpleTypes
module SimpleTypeTests
TYPES = {
'integer' => 5,
'number' => 5.0,
'string' => 'str',
'boolean' => true,
'object' => {},
'array' => [],
'null' => nil
}
TYPES.each do |name, value|
other_values = TYPES.values.reject { |v| v == value }
define_method(:"test_#{name}_type_property") do
schema = {
'properties' => { 'a' => { 'type' => name } }
}
assert_valid schema, {'a' => value}
other_values.each do |other_value|
refute_valid schema, {'a' => other_value}
end
end
define_method(:"test_#{name}_type_value") do
schema = { 'type' => name }
assert_valid schema, value
other_values.each do |other_value|
schema = { 'type' => name }
refute_valid schema, other_value
end
end
end
def test_type_union
schema = { 'type' => ['integer', 'string'] }
assert_valid schema, 5
assert_valid schema, 'str'
refute_valid schema, nil
refute_valid schema, [5, 'str']
end
end
# The draft1..3 schemas support an additional type, `any`.
module AnyTypeTests
def test_any_type
schema = { 'type' => 'any' }
SimpleTypeTests::TYPES.values.each do |value|
assert_valid schema, value
end
end
end
# The draft1..3 schemas support schemas as values for `type`.
module SchemaUnionTypeTests
def test_union_type_with_schemas
schema = {
'properties' => {
'a' => {
'type' => [
{'type' => 'string'},
{'type' => 'object', 'properties' => { 'b' => { 'type' => 'integer' }}}
]
}
}
}
assert_valid schema, {'a' => 'test'}
refute_valid schema, {'a' => 5}
assert_valid schema, {'a' => {'b' => 5}}
refute_valid schema, {'a' => {'b' => 'taco'}}
end
end
end
ruby-json-schema-2.8.1/test/type_attribute_test.rb 0000664 0000000 0000000 00000001161 13411675645 0022332 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class TypeAttributeTest < Minitest::Test
def test_type_of_data
assert_equal(type_of_data(String.new), 'string')
assert_equal(type_of_data(Numeric.new), 'number')
assert_equal(type_of_data(1), 'integer')
assert_equal(type_of_data(true), 'boolean')
assert_equal(type_of_data(false), 'boolean')
assert_equal(type_of_data(Hash.new), 'object')
assert_equal(type_of_data(nil), 'null')
assert_equal(type_of_data(Object.new), 'any')
end
private
def type_of_data(data)
JSON::Schema::TypeAttribute.type_of_data(data)
end
end
ruby-json-schema-2.8.1/test/uri_parsing_test.rb 0000664 0000000 0000000 00000003241 13411675645 0021611 0 ustar 00root root 0000000 0000000 # coding: utf-8
require File.expand_path('../support/test_helper', __FILE__)
class UriParsingTest < Minitest::Test
def test_asian_characters
schema = {
"$schema"=> "http://json-schema.org/draft-04/schema#",
"id"=> "http://俺:鍵@例え.テスト/p?条件#ここ#",
"type" => "object",
"required" => ["a"],
"properties" => {
"a" => {
"id" => "a",
"type" => "integer"
}
}
}
data = { "a" => 5 }
assert_valid schema, data
end
def test_schema_ref_with_empty_fragment
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"type" => "object",
"required" => ["names"],
"properties"=> {
"names"=> {
"type"=> "array",
"items"=> {
"anyOf"=> [
{ "$ref" => "test/schemas/ref john with spaces schema.json#" },
]
}
}
}
}
data = {"names" => [{"first" => "john"}]}
assert_valid schema, data
end
def test_schema_ref_from_file_with_spaces
schema = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"type" => "object",
"required" => ["names"],
"properties"=> {
"names"=> {
"type"=> "array",
"items"=> {
"anyOf"=> [
{ "$ref" => "test/schemas/ref john with spaces schema.json" }
]
}
}
}
}
data = {"names" => [{"first" => "john"}]}
assert_valid schema, data
end
def test_schema_from_file_with_spaces
data = {"first" => "john"}
schema = "test/schemas/ref john with spaces schema.json"
assert_valid schema, data
end
end
ruby-json-schema-2.8.1/test/uri_util_test.rb 0000664 0000000 0000000 00000017030 13411675645 0021124 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class UriUtilTest < Minitest::Test
def populate_cache_with(str, &blk)
cached_uri = Addressable::URI.parse(str)
Addressable::URI.stub(:parse, cached_uri, &blk)
cached_uri
end
def teardown
JSON::Util::URI.clear_cache
end
def test_normalized_uri
str = "https://www.google.com/search"
uri = Addressable::URI.new(scheme: 'https',
host: 'www.google.com',
path: 'search')
assert_equal uri, JSON::Util::URI.normalized_uri(str, '/home')
end
def test_normalized_uri_with_empty_fragment
str = "https://www.google.com/search#"
uri = Addressable::URI.new(scheme: 'https',
host: 'www.google.com',
path: 'search',
fragment: nil)
assert_equal uri, JSON::Util::URI.normalized_uri(str, '/home')
end
def test_normalized_uri_with_fragment
str = "https://www.google.com/search#foo"
uri = Addressable::URI.new(scheme: 'https',
host: 'www.google.com',
path: 'search',
fragment: 'foo')
assert_equal uri, JSON::Util::URI.normalized_uri(str, '/home')
end
def test_normalized_uri_for_absolute_path
str = "/foo/bar.json"
uri = Addressable::URI.new(scheme: 'file',
host: '',
path: '/foo/bar.json')
assert_equal uri, JSON::Util::URI.normalized_uri(str, '/home')
end
def test_normalized_uri_for_relative_path
str = "foo/bar.json"
uri = Addressable::URI.new(scheme: 'file',
host: '',
path: '/home/foo/bar.json')
assert_equal uri, JSON::Util::URI.normalized_uri(str, '/home')
end
def test_normalized_uri_for_file_path_with_host
str = "file://localhost/foo/bar.json"
uri = Addressable::URI.new(scheme: 'file',
host: 'localhost',
path: '/foo/bar.json')
assert_equal uri, JSON::Util::URI.normalized_uri(str, '/home')
end
def test_uri_parse
str = "https://www.google.com/search"
uri = Addressable::URI.new(scheme: 'https',
host: 'www.google.com',
path: 'search')
assert_equal uri, JSON::Util::URI.parse(str)
end
def test_invalid_uri_parse
uri = ":::::::"
assert_raises(JSON::Schema::UriError) do
JSON::Util::URI.parse(uri)
end
end
def test_normalization_cache
cached_uri = populate_cache_with('www.google.com') do
JSON::Util::URI.normalized_uri('foo')
end
assert_equal(cached_uri, JSON::Util::URI.normalized_uri('foo'))
JSON::Util::URI.clear_cache
refute_equal(cached_uri, JSON::Util::URI.normalized_uri('foo'))
end
def test_parse_cache
cached_uri = populate_cache_with('www.google.com') do
JSON::Util::URI.parse('foo')
end
assert_equal(cached_uri, JSON::Util::URI.parse('foo'))
JSON::Util::URI.clear_cache
refute_equal(cached_uri, JSON::Util::URI.parse('foo'))
end
def test_validator_clear_cache_for_normalized_uri
cached_uri = populate_cache_with('www.google.com') do
JSON::Util::URI.normalized_uri('foo')
end
assert_equal(cached_uri, JSON::Util::URI.normalized_uri('foo'))
validation_errors({"type" => "string"}, "foo", :clear_cache => true)
refute_equal(cached_uri, JSON::Util::URI.normalized_uri('foo'))
end
def test_validator_clear_cache_for_parse
cached_uri = populate_cache_with('www.google.com') do
JSON::Util::URI.parse('foo')
end
assert_equal(cached_uri, JSON::Util::URI.parse('foo'))
validation_errors({"type" => "string"}, "foo", :clear_cache => true)
refute_equal(cached_uri, JSON::Util::URI.parse('foo'))
end
def test_ref_fragment_path
uri = '#some-thing'
base = 'http://www.example.com/foo/#bar'
assert_equal Addressable::URI.parse('http://www.example.com/foo/#some-thing'), JSON::Util::URI.normalize_ref(uri, base)
assert_equal Addressable::URI.parse('http://www.example.com/foo/#'), JSON::Util::URI.absolutize_ref(uri, base)
end
def test_ref_file_path
uri = '/some/thing'
base = 'http://www.example.com/foo/#bar'
assert_equal Addressable::URI.parse('http://www.example.com/some/thing#'), JSON::Util::URI.normalize_ref(uri, base)
assert_equal Addressable::URI.parse('http://www.example.com/some/thing#'), JSON::Util::URI.absolutize_ref(uri, base)
end
def test_ref_uri
uri = 'http://foo-bar.com'
base = 'http://www.example.com/foo/#bar'
assert_equal Addressable::URI.parse('http://foo-bar.com/#'), JSON::Util::URI.normalize_ref(uri, base)
assert_equal Addressable::URI.parse('http://foo-bar.com/#'), JSON::Util::URI.absolutize_ref(uri, base)
end
def test_ref_uri_with_path
uri = 'http://foo-bar.com/some/thing'
base = 'http://www.example.com/foo/#bar'
assert_equal Addressable::URI.parse('http://foo-bar.com/some/thing#'), JSON::Util::URI.normalize_ref(uri, base)
assert_equal Addressable::URI.parse('http://foo-bar.com/some/thing#'), JSON::Util::URI.absolutize_ref(uri, base)
end
def test_ref_uri_with_fragment
uri = 'http://foo-bar.com/some/thing#foo'
base = 'http://www.example.com/hello/#world'
assert_equal Addressable::URI.parse('http://foo-bar.com/some/thing#foo'), JSON::Util::URI.normalize_ref(uri, base)
assert_equal Addressable::URI.parse('http://foo-bar.com/some/thing#'), JSON::Util::URI.absolutize_ref(uri, base)
end
def test_ref_uri_with_fragment_and_base_with_no_fragment
uri = 'http://foo-bar.com/some/thing#foo'
base = 'http://www.example.com/hello'
assert_equal Addressable::URI.parse('http://foo-bar.com/some/thing#foo'), JSON::Util::URI.normalize_ref(uri, base)
assert_equal Addressable::URI.parse('http://foo-bar.com/some/thing#'), JSON::Util::URI.absolutize_ref(uri, base)
end
def test_ref_relative_path
uri = 'hello/world'
base = 'http://www.example.com/foo/#bar'
assert_equal Addressable::URI.parse('http://www.example.com/foo/hello/world#'), JSON::Util::URI.normalize_ref(uri, base)
assert_equal Addressable::URI.parse('http://www.example.com/foo/hello/world#'), JSON::Util::URI.absolutize_ref(uri, base)
end
def test_ref_addressable_uri_with_host
uri = Addressable::URI.new(:host => 'foo-bar.com')
base = 'http://www.example.com/hello/#world'
assert_equal Addressable::URI.parse('http://www.example.com/foo-bar.com#'), JSON::Util::URI.normalize_ref(uri, base)
assert_equal Addressable::URI.parse('http://www.example.com/hello/#world'), JSON::Util::URI.absolutize_ref(uri, base)
end
def test_ref_addressable_uri_with_host_and_path
uri = Addressable::URI.new(:host => 'foo-bar.com', :path => '/hello/world')
base = 'http://www.example.com/a/#b'
assert_equal Addressable::URI.parse('http://www.example.com/foo-bar.com/hello/world#'), JSON::Util::URI.normalize_ref(uri, base)
assert_equal Addressable::URI.parse('http://www.example.com/hello/world'), JSON::Util::URI.absolutize_ref(uri, base)
end
def test_ref_addressable_uri_with_shceme_host_and_path
uri = Addressable::URI.new(:scheme => 'https', :host => 'foo-bar.com', :path => '/hello/world')
base = 'http://www.example.com/a/#b'
assert_equal Addressable::URI.parse('https://foo-bar.com/hello/world#'), JSON::Util::URI.normalize_ref(uri, base)
assert_equal Addressable::URI.parse('https://foo-bar.com/hello/world'), JSON::Util::URI.absolutize_ref(uri, base)
end
end
ruby-json-schema-2.8.1/test/validator_schema_reader_test.rb 0000664 0000000 0000000 00000003033 13411675645 0024115 0 ustar 00root root 0000000 0000000 require File.expand_path('../support/test_helper', __FILE__)
class ValidatorSchemaReaderTest < Minitest::Test
class MockReader < JSON::Schema::Reader
def read(location)
return super unless location.to_s == 'http://any.url/at/all'
schema = {
'$schema' => 'http://json-schema.org/draft-04/schema#',
'type' => 'string',
'minLength' => 2
}
JSON::Schema.new(schema, Addressable::URI.parse(location.to_s))
end
end
def setup
@original_reader = JSON::Validator.schema_reader
end
def teardown
JSON::Validator.schema_reader = @original_reader
end
def test_default_schema_reader
reader = JSON::Validator.schema_reader
assert reader.accept_uri?(Addressable::URI.parse('http://example.com'))
assert reader.accept_file?(Pathname.new('/etc/passwd'))
end
def test_set_default_schema_reader
JSON::Validator.schema_reader = MockReader.new
schema = { '$ref' => 'http://any.url/at/all' }
assert_valid schema, 'abc'
refute_valid schema, 'a'
end
def test_validate_with_reader
reader = MockReader.new
schema = { '$ref' => 'http://any.url/at/all' }
assert_valid schema, 'abc', :schema_reader => reader
refute_valid schema, 'a', :schema_reader => reader
end
def test_validate_list_with_reader
reader = MockReader.new
schema = { '$ref' => 'http://any.url/at/all' }
assert_valid schema, ['abc', 'def'], :schema_reader => reader, :list => true
refute_valid schema, ['abc', 'a'], :schema_reader => reader, :list => true
end
end