pax_global_header 0000666 0000000 0000000 00000000064 13046321150 0014505 g ustar 00root root 0000000 0000000 52 comment=20734c1bc388fdc16d53837b2ce9599f21cfa4b7
json-schema-2.8.0/ 0000775 0000000 0000000 00000000000 13046321150 0013723 5 ustar 00root root 0000000 0000000 json-schema-2.8.0/.gitignore 0000664 0000000 0000000 00000000067 13046321150 0015716 0 ustar 00root root 0000000 0000000 /.project
.*.swp
pkg
*.gem
/Gemfile.lock
.bundle
.idea
json-schema-2.8.0/.gitmodules 0000664 0000000 0000000 00000000212 13046321150 0016073 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
json-schema-2.8.0/.travis.yml 0000664 0000000 0000000 00000000755 13046321150 0016043 0 ustar 00root root 0000000 0000000 language: "ruby"
rvm:
- "2.0"
- "2.1"
- "2.2"
- "2.3.3"
- "2.4.0"
- "jruby-9.1.7.0"
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.3.3"
gemfile: "gemfiles/Gemfile.multi_json.x"
- rvm: "2.3.3"
gemfile: "gemfiles/Gemfile.yajl-ruby.x"
- rvm: "2.3.3"
gemfile: "gemfiles/Gemfile.uuidtools.x"
json-schema-2.8.0/CHANGELOG.md 0000664 0000000 0000000 00000004040 13046321150 0015532 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.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`
json-schema-2.8.0/CONTRIBUTING.md 0000664 0000000 0000000 00000001576 13046321150 0016165 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.
json-schema-2.8.0/CONTRIBUTORS.md 0000664 0000000 0000000 00000001552 13046321150 0016205 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
json-schema-2.8.0/Gemfile 0000664 0000000 0000000 00000000124 13046321150 0015213 0 ustar 00root root 0000000 0000000 source "https://rubygems.org"
gemspec
gem "json", ">= 1.7", :platforms => :mri_19
json-schema-2.8.0/LICENSE.md 0000664 0000000 0000000 00000002065 13046321150 0015332 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. json-schema-2.8.0/README.md 0000664 0000000 0000000 00000032642 13046321150 0015211 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"})
```
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.
json-schema-2.8.0/Rakefile 0000664 0000000 0000000 00000001136 13046321150 0015371 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
sh "git submodule update --remote --quiet"
end
Rake::TestTask.new do |t|
t.libs << "."
# disabled warnings because addressable 2.4 has lots of them
t.warning = false
t.verbose = true
t.test_files = FileList.new('test/*_test.rb')
end
task :test => :update_common_tests
task :default => :test
json-schema-2.8.0/VERSION.yml 0000664 0000000 0000000 00000000033 13046321150 0015567 0 ustar 00root root 0000000 0000000 major: 2
minor: 8
patch: 0
json-schema-2.8.0/gemfiles/ 0000775 0000000 0000000 00000000000 13046321150 0015516 5 ustar 00root root 0000000 0000000 json-schema-2.8.0/gemfiles/Gemfile.multi_json.x 0000664 0000000 0000000 00000000110 13046321150 0021431 0 ustar 00root root 0000000 0000000 source "https://rubygems.org"
gemspec :path => "../"
gem "multi_json"
json-schema-2.8.0/gemfiles/Gemfile.ruby_19.x 0000664 0000000 0000000 00000000147 13046321150 0020552 0 ustar 00root root 0000000 0000000 source "https://rubygems.org"
gemspec :path => "../"
gem "json", "~> 1.0"
gem "addressable", "< 2.5"
json-schema-2.8.0/gemfiles/Gemfile.uuidtools.x 0000664 0000000 0000000 00000000107 13046321150 0021303 0 ustar 00root root 0000000 0000000 source "https://rubygems.org"
gemspec :path => "../"
gem "uuidtools"
json-schema-2.8.0/gemfiles/Gemfile.yajl-ruby.x 0000664 0000000 0000000 00000000107 13046321150 0021172 0 ustar 00root root 0000000 0000000 source "https://rubygems.org"
gemspec :path => "../"
gem "yajl-ruby"
json-schema-2.8.0/json-schema.gemspec 0000664 0000000 0000000 00000001576 13046321150 0017510 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
json-schema-2.8.0/lib/ 0000775 0000000 0000000 00000000000 13046321150 0014471 5 ustar 00root root 0000000 0000000 json-schema-2.8.0/lib/json-schema.rb 0000664 0000000 0000000 00000001525 13046321150 0017230 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/attributes/formats/*.rb")].each {|file| require file }
Dir[File.join(File.dirname(__FILE__), "json-schema/validators/*.rb")].sort!.each {|file| require file }
json-schema-2.8.0/lib/json-schema/ 0000775 0000000 0000000 00000000000 13046321150 0016700 5 ustar 00root root 0000000 0000000 json-schema-2.8.0/lib/json-schema/attribute.rb 0000664 0000000 0000000 00000002765 13046321150 0021242 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
json-schema-2.8.0/lib/json-schema/attributes/ 0000775 0000000 0000000 00000000000 13046321150 0021066 5 ustar 00root root 0000000 0000000 json-schema-2.8.0/lib/json-schema/attributes/additionalitems.rb 0000664 0000000 0000000 00000002063 13046321150 0024566 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
json-schema-2.8.0/lib/json-schema/attributes/additionalproperties.rb 0000664 0000000 0000000 00000004451 13046321150 0025644 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
json-schema-2.8.0/lib/json-schema/attributes/allof.rb 0000664 0000000 0000000 00000003117 13046321150 0022512 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
json-schema-2.8.0/lib/json-schema/attributes/anyof.rb 0000664 0000000 0000000 00000003477 13046321150 0022542 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
json-schema-2.8.0/lib/json-schema/attributes/dependencies.rb 0000664 0000000 0000000 00000003231 13046321150 0024040 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
class DependenciesV4Attribute < DependenciesAttribute
def self.accept_value?(value)
value.is_a?(Array) || value.is_a?(Hash)
end
end
end
end
json-schema-2.8.0/lib/json-schema/attributes/disallow.rb 0000664 0000000 0000000 00000000606 13046321150 0023233 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
json-schema-2.8.0/lib/json-schema/attributes/divisibleby.rb 0000664 0000000 0000000 00000001271 13046321150 0023721 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.new(data.to_s) % BigDecimal.new(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
json-schema-2.8.0/lib/json-schema/attributes/enum.rb 0000664 0000000 0000000 00000001366 13046321150 0022365 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
json-schema-2.8.0/lib/json-schema/attributes/extends.rb 0000664 0000000 0000000 00000003265 13046321150 0023073 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
json-schema-2.8.0/lib/json-schema/attributes/format.rb 0000664 0000000 0000000 00000001000 13046321150 0022672 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
json-schema-2.8.0/lib/json-schema/attributes/formats/ 0000775 0000000 0000000 00000000000 13046321150 0022541 5 ustar 00root root 0000000 0000000 json-schema-2.8.0/lib/json-schema/attributes/formats/custom.rb 0000664 0000000 0000000 00000001247 13046321150 0024404 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
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
json-schema-2.8.0/lib/json-schema/attributes/formats/date.rb 0000664 0000000 0000000 00000001542 13046321150 0024005 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
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
json-schema-2.8.0/lib/json-schema/attributes/formats/date_time.rb 0000664 0000000 0000000 00000003276 13046321150 0025031 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
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
json-schema-2.8.0/lib/json-schema/attributes/formats/date_time_v4.rb 0000664 0000000 0000000 00000001041 13046321150 0025426 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
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
json-schema-2.8.0/lib/json-schema/attributes/formats/ip.rb 0000664 0000000 0000000 00000002021 13046321150 0023471 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
json-schema-2.8.0/lib/json-schema/attributes/formats/time.rb 0000664 0000000 0000000 00000002003 13046321150 0024017 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
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
json-schema-2.8.0/lib/json-schema/attributes/formats/uri.rb 0000664 0000000 0000000 00000001132 13046321150 0023662 0 ustar 00root root 0000000 0000000 require 'json-schema/attribute'
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
json-schema-2.8.0/lib/json-schema/attributes/items.rb 0000664 0000000 0000000 00000001520 13046321150 0022532 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
json-schema-2.8.0/lib/json-schema/attributes/limit.rb 0000664 0000000 0000000 00000007704 13046321150 0022541 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
class MinLengthAttribute < LimitAttribute
def self.acceptable_type
String
end
def self.limit_name
'minLength'
end
def self.error_message(schema)
"was not of a minimum string length of #{limit(schema)}"
end
def self.value(data)
data.length
end
end
class MaxLengthAttribute < MinLengthAttribute
def self.limit_name
'maxLength'
end
def self.error_message(schema)
"was not of a maximum string length of #{limit(schema)}"
end
end
class MinItemsAttribute < LimitAttribute
def self.acceptable_type
Array
end
def self.value(data)
data.length
end
def self.limit_name
'minItems'
end
def self.error_message(schema)
"did not contain a minimum number of items #{limit(schema)}"
end
end
class MaxItemsAttribute < MinItemsAttribute
def self.limit_name
'maxItems'
end
def self.error_message(schema)
"had more items than the allowed #{limit(schema)}"
end
end
class MinPropertiesAttribute < LimitAttribute
def self.acceptable_type
Hash
end
def self.value(data)
data.size
end
def self.limit_name
'minProperties'
end
def self.error_message(schema)
"did not contain a minimum number of properties #{limit(schema)}"
end
end
class MaxPropertiesAttribute < MinPropertiesAttribute
def self.limit_name
'maxProperties'
end
def self.error_message(schema)
"had more properties than the allowed #{limit(schema)}"
end
end
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
class MaximumAttribute < NumericLimitAttribute
def self.limit_name
'maximum'
end
def self.exclusive?(schema)
schema['exclusiveMaximum']
end
end
class MaximumInclusiveAttribute < MaximumAttribute
def self.exclusive?(schema)
schema['maximumCanEqual'] == false
end
end
class MinimumAttribute < NumericLimitAttribute
def self.limit_name
'minimum'
end
def self.exclusive?(schema)
schema['exclusiveMinimum']
end
end
class MinimumInclusiveAttribute < MinimumAttribute
def self.exclusive?(schema)
schema['minimumCanEqual'] == false
end
end
end
end
json-schema-2.8.0/lib/json-schema/attributes/maxdecimal.rb 0000664 0000000 0000000 00000001223 13046321150 0023515 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
json-schema-2.8.0/lib/json-schema/attributes/multipleof.rb 0000664 0000000 0000000 00000000306 13046321150 0023572 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
json-schema-2.8.0/lib/json-schema/attributes/not.rb 0000664 0000000 0000000 00000002155 13046321150 0022216 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
json-schema-2.8.0/lib/json-schema/attributes/oneof.rb 0000664 0000000 0000000 00000003616 13046321150 0022527 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
json-schema-2.8.0/lib/json-schema/attributes/pattern.rb 0000664 0000000 0000000 00000001163 13046321150 0023071 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
json-schema-2.8.0/lib/json-schema/attributes/patternproperties.rb 0000664 0000000 0000000 00000001345 13046321150 0025210 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
json-schema-2.8.0/lib/json-schema/attributes/properties.rb 0000664 0000000 0000000 00000005166 13046321150 0023617 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
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
json-schema-2.8.0/lib/json-schema/attributes/properties_optional.rb 0000664 0000000 0000000 00000001717 13046321150 0025522 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
json-schema-2.8.0/lib/json-schema/attributes/ref.rb 0000664 0000000 0000000 00000004460 13046321150 0022173 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
json-schema-2.8.0/lib/json-schema/attributes/required.rb 0000664 0000000 0000000 00000002030 13046321150 0023226 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
json-schema-2.8.0/lib/json-schema/attributes/type.rb 0000664 0000000 0000000 00000005705 13046321150 0022403 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
json-schema-2.8.0/lib/json-schema/attributes/type_v4.rb 0000664 0000000 0000000 00000001612 13046321150 0023005 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
json-schema-2.8.0/lib/json-schema/attributes/uniqueitems.rb 0000664 0000000 0000000 00000000776 13046321150 0023775 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
json-schema-2.8.0/lib/json-schema/errors/ 0000775 0000000 0000000 00000000000 13046321150 0020214 5 ustar 00root root 0000000 0000000 json-schema-2.8.0/lib/json-schema/errors/custom_format_error.rb 0000664 0000000 0000000 00000000131 13046321150 0024627 0 ustar 00root root 0000000 0000000 module JSON
class Schema
class CustomFormatError < StandardError
end
end
end
json-schema-2.8.0/lib/json-schema/errors/json_load_error.rb 0000664 0000000 0000000 00000000125 13046321150 0023720 0 ustar 00root root 0000000 0000000 module JSON
class Schema
class JsonLoadError < StandardError
end
end
end
json-schema-2.8.0/lib/json-schema/errors/json_parse_error.rb 0000664 0000000 0000000 00000000126 13046321150 0024114 0 ustar 00root root 0000000 0000000 module JSON
class Schema
class JsonParseError < StandardError
end
end
end
json-schema-2.8.0/lib/json-schema/errors/schema_error.rb 0000664 0000000 0000000 00000000123 13046321150 0023206 0 ustar 00root root 0000000 0000000 module JSON
class Schema
class SchemaError < StandardError
end
end
end
json-schema-2.8.0/lib/json-schema/errors/schema_parse_error.rb 0000664 0000000 0000000 00000000163 13046321150 0024404 0 ustar 00root root 0000000 0000000 require 'json/common'
module JSON
class Schema
class SchemaParseError < JSON::ParserError
end
end
end
json-schema-2.8.0/lib/json-schema/errors/uri_error.rb 0000664 0000000 0000000 00000000120 13046321150 0022542 0 ustar 00root root 0000000 0000000 module JSON
class Schema
class UriError < StandardError
end
end
end
json-schema-2.8.0/lib/json-schema/errors/validation_error.rb 0000664 0000000 0000000 00000003137 13046321150 0024110 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
json-schema-2.8.0/lib/json-schema/schema.rb 0000664 0000000 0000000 00000003300 13046321150 0020461 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
json-schema-2.8.0/lib/json-schema/schema/ 0000775 0000000 0000000 00000000000 13046321150 0020140 5 ustar 00root root 0000000 0000000 json-schema-2.8.0/lib/json-schema/schema/reader.rb 0000664 0000000 0000000 00000010671 13046321150 0021734 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
json-schema-2.8.0/lib/json-schema/schema/validator.rb 0000664 0000000 0000000 00000002240 13046321150 0022450 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
json-schema-2.8.0/lib/json-schema/util/ 0000775 0000000 0000000 00000000000 13046321150 0017655 5 ustar 00root root 0000000 0000000 json-schema-2.8.0/lib/json-schema/util/array_set.rb 0000664 0000000 0000000 00000001011 13046321150 0022164 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
json-schema-2.8.0/lib/json-schema/util/uri.rb 0000664 0000000 0000000 00000005430 13046321150 0021003 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
json-schema-2.8.0/lib/json-schema/util/uuid.rb 0000664 0000000 0000000 00000020427 13046321150 0021155 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 json-schema-2.8.0/lib/json-schema/validator.rb 0000664 0000000 0000000 00000046444 13046321150 0021226 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
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
# 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
json-schema-2.8.0/lib/json-schema/validators/ 0000775 0000000 0000000 00000000000 13046321150 0021050 5 ustar 00root root 0000000 0000000 json-schema-2.8.0/lib/json-schema/validators/draft1.rb 0000664 0000000 0000000 00000003124 13046321150 0022556 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
json-schema-2.8.0/lib/json-schema/validators/draft2.rb 0000664 0000000 0000000 00000003225 13046321150 0022561 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
json-schema-2.8.0/lib/json-schema/validators/draft3.rb 0000664 0000000 0000000 00000003651 13046321150 0022565 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
json-schema-2.8.0/lib/json-schema/validators/draft4.rb 0000664 0000000 0000000 00000004453 13046321150 0022567 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
json-schema-2.8.0/lib/json-schema/validators/draft6.rb 0000664 0000000 0000000 00000004453 13046321150 0022571 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-06/schema#")
@names = ["draft6", "http://json-schema.org/draft-06/schema#"]
@metaschema_name = "draft-06.json"
end
JSON::Validator.register_validator(self.new)
JSON::Validator.register_default_validator(self.new)
end
end
end
json-schema-2.8.0/lib/json-schema/validators/hyper-draft1.rb 0000664 0000000 0000000 00000000404 13046321150 0023701 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
json-schema-2.8.0/lib/json-schema/validators/hyper-draft2.rb 0000664 0000000 0000000 00000000404 13046321150 0023702 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
json-schema-2.8.0/lib/json-schema/validators/hyper-draft3.rb 0000664 0000000 0000000 00000000404 13046321150 0023703 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
json-schema-2.8.0/lib/json-schema/validators/hyper-draft4.rb 0000664 0000000 0000000 00000000404 13046321150 0023704 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
json-schema-2.8.0/lib/json-schema/validators/hyper-draft6.rb 0000664 0000000 0000000 00000000404 13046321150 0023706 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
json-schema-2.8.0/resources/ 0000775 0000000 0000000 00000000000 13046321150 0015735 5 ustar 00root root 0000000 0000000 json-schema-2.8.0/resources/draft-01.json 0000664 0000000 0000000 00000004713 13046321150 0020153 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" : {}
} json-schema-2.8.0/resources/draft-02.json 0000664 0000000 0000000 00000005244 13046321150 0020154 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" : {}
} json-schema-2.8.0/resources/draft-03.json 0000664 0000000 0000000 00000007427 13046321150 0020162 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": {}
}
json-schema-2.8.0/resources/draft-04.json 0000664 0000000 0000000 00000010427 13046321150 0020155 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": {}
}
json-schema-2.8.0/resources/draft-06.json 0000664 0000000 0000000 00000010427 13046321150 0020157 0 ustar 00root root 0000000 0000000 {
"id": "http://json-schema.org/draft-06/schema#",
"$schema": "http://json-schema.org/draft-06/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": {}
}
json-schema-2.8.0/test/ 0000775 0000000 0000000 00000000000 13046321150 0014702 5 ustar 00root root 0000000 0000000 json-schema-2.8.0/test/all_of_ref_schema_test.rb 0000664 0000000 0000000 00000002245 13046321150 0021701 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
json-schema-2.8.0/test/any_of_ref_schema_test.rb 0000664 0000000 0000000 00000003074 13046321150 0021721 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
json-schema-2.8.0/test/bad_schema_ref_test.rb 0000664 0000000 0000000 00000002562 13046321150 0021175 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
json-schema-2.8.0/test/caching_test.rb 0000664 0000000 0000000 00000002223 13046321150 0017661 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
json-schema-2.8.0/test/common_test_suite_test.rb 0000664 0000000 0000000 00000006203 13046321150 0022027 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__)
# 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.
IGNORED_TESTS = Hash.new { |h,k| h[k] = [] }.merge({
"draft3/optional/jsregex.json" => :all,
"draft3/optional/format.json" => [
"validation of regular expressions",
"validation of e-mail addresses",
"validation of URIs",
"validation of host names",
"validation of CSS colors"
],
"draft3/ref.json" => [
"ref overrides any sibling keywords/remote ref valid, maxItems ignored"
],
"draft4/optional/format.json" => [
"validation of URIs",
"validation of e-mail addresses",
"validation of host names"
],
"draft4/optional/ecmascript-regex.json" => [
"ECMA 262 regex non-compliance/ECMA 262 has no support for \\Z anchor from .NET"
],
"draft4/ref.json" => [
"ref overrides any sibling keywords/remote ref valid, maxItems ignored",
"ref overrides any sibling keywords/ref valid, maxItems ignored"
],
"draft6/optional/format.json" => [
"validation of URIs",
"validation of e-mail addresses",
"validation of host names"
],
"draft6/optional/ecmascript-regex.json" => [
"ECMA 262 regex non-compliance/ECMA 262 has no support for \\Z anchor from .NET"
],
"draft6/ref.json" => [
"ref overrides any sibling keywords/remote ref valid, maxItems ignored",
"ref overrides any sibling keywords/ref valid, maxItems ignored"
]
})
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
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|
next if IGNORED_TESTS[rel_file] == :all
next if IGNORED_TESTS[rel_file].any? { |ignored|
base_description == ignored || "#{base_description}/#{t['description']}" == ignored
}
err_id = "#{rel_file}: #{base_description}/#{t['description']}"
define_method("test_#{err_id}") do
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
json-schema-2.8.0/test/custom_format_test.rb 0000664 0000000 0000000 00000012635 13046321150 0021157 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-06/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
json-schema-2.8.0/test/data/ 0000775 0000000 0000000 00000000000 13046321150 0015613 5 ustar 00root root 0000000 0000000 json-schema-2.8.0/test/data/all_of_ref_data.json 0000664 0000000 0000000 00000000026 13046321150 0021565 0 ustar 00root root 0000000 0000000 {
"name" : "john"
}
json-schema-2.8.0/test/data/any_of_ref_data.json 0000664 0000000 0000000 00000000076 13046321150 0021611 0 ustar 00root root 0000000 0000000 {
"names" :
[ "john"
, "jane"
, "jimmy"
]
}
json-schema-2.8.0/test/data/bad_data_1.json 0000664 0000000 0000000 00000000022 13046321150 0020437 0 ustar 00root root 0000000 0000000 {
"a" : "poop"
} json-schema-2.8.0/test/data/good_data_1.json 0000664 0000000 0000000 00000000015 13046321150 0020643 0 ustar 00root root 0000000 0000000 {
"a" : 5
} json-schema-2.8.0/test/data/one_of_ref_links_data.json 0000664 0000000 0000000 00000000233 13046321150 0022776 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" }
]
}
json-schema-2.8.0/test/draft1_test.rb 0000664 0000000 0000000 00000005557 13046321150 0017463 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
json-schema-2.8.0/test/draft2_test.rb 0000664 0000000 0000000 00000004776 13046321150 0017466 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
json-schema-2.8.0/test/draft3_test.rb 0000664 0000000 0000000 00000030201 13046321150 0017445 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
json-schema-2.8.0/test/draft4_test.rb 0000664 0000000 0000000 00000041621 13046321150 0017456 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
json-schema-2.8.0/test/extended_schema_test.rb 0000664 0000000 0000000 00000003460 13046321150 0021411 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
json-schema-2.8.0/test/extends_nested_test.rb 0000664 0000000 0000000 00000002624 13046321150 0021306 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
json-schema-2.8.0/test/files_test.rb 0000664 0000000 0000000 00000004333 13046321150 0017373 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
json-schema-2.8.0/test/fragment_resolution_test.rb 0000664 0000000 0000000 00000001445 13046321150 0022360 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
end
json-schema-2.8.0/test/fragment_validation_with_ref_test.rb 0000664 0000000 0000000 00000001477 13046321150 0024203 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 test_validation_of_fragment
data = [{"content" => "ohai", "author" => "Bob"}]
assert_valid whole_schema, data, :fragment => "#/definitions/posts"
end
end
json-schema-2.8.0/test/full_validation_test.rb 0000664 0000000 0000000 00000011623 13046321150 0021445 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
json-schema-2.8.0/test/initialize_data_test.rb 0000664 0000000 0000000 00000007363 13046321150 0021431 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_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_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
json-schema-2.8.0/test/list_option_test.rb 0000664 0000000 0000000 00000001147 13046321150 0020634 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
json-schema-2.8.0/test/load_ref_schema_test.rb 0000664 0000000 0000000 00000002206 13046321150 0021361 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
json-schema-2.8.0/test/merge_missing_values_test.rb 0000664 0000000 0000000 00000003341 13046321150 0022476 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
json-schema-2.8.0/test/min_items_test.rb 0000664 0000000 0000000 00000000624 13046321150 0020254 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
json-schema-2.8.0/test/one_of_test.rb 0000664 0000000 0000000 00000005423 13046321150 0017537 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
json-schema-2.8.0/test/relative_definition_test.rb 0000664 0000000 0000000 00000001065 13046321150 0022313 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
json-schema-2.8.0/test/ruby_schema_test.rb 0000664 0000000 0000000 00000002410 13046321150 0020564 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
json-schema-2.8.0/test/schema_reader_test.rb 0000664 0000000 0000000 00000004650 13046321150 0021055 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
json-schema-2.8.0/test/schema_validation_test.rb 0000664 0000000 0000000 00000011013 13046321150 0021734 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
json-schema-2.8.0/test/schemas/ 0000775 0000000 0000000 00000000000 13046321150 0016325 5 ustar 00root root 0000000 0000000 json-schema-2.8.0/test/schemas/address_microformat.json 0000664 0000000 0000000 00000001200 13046321150 0023240 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"
}
}
json-schema-2.8.0/test/schemas/all_of_ref_base_schema.json 0000664 0000000 0000000 00000000121 13046321150 0023614 0 ustar 00root root 0000000 0000000 {
"type": "object",
"properties" : {
"name" : { "type": "integer" }
}
}
json-schema-2.8.0/test/schemas/all_of_ref_schema.json 0000664 0000000 0000000 00000000220 13046321150 0022622 0 ustar 00root root 0000000 0000000 { "$schema" : "http://json-schema.org/draft-04/schema#",
"type" : "object",
"allOf" :
[ { "$ref" : "all_of_ref_base_schema.json" }
]
}
json-schema-2.8.0/test/schemas/any_of_ref_jane_schema.json 0000664 0000000 0000000 00000000143 13046321150 0023642 0 ustar 00root root 0000000 0000000 { "$schema" : "http://json-schema.org/draft-04/schema#"
, "type" : "string"
, "pattern" : "jane"
}
json-schema-2.8.0/test/schemas/any_of_ref_jimmy_schema.json 0000664 0000000 0000000 00000000144 13046321150 0024053 0 ustar 00root root 0000000 0000000 { "$schema" : "http://json-schema.org/draft-04/schema#"
, "type" : "string"
, "pattern" : "jimmy"
}
json-schema-2.8.0/test/schemas/any_of_ref_john_schema.json 0000664 0000000 0000000 00000000143 13046321150 0023663 0 ustar 00root root 0000000 0000000 { "$schema" : "http://json-schema.org/draft-04/schema#"
, "type" : "string"
, "pattern" : "john"
}
json-schema-2.8.0/test/schemas/any_of_ref_schema.json 0000664 0000000 0000000 00000000542 13046321150 0022650 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" }
]
}
}
}
}
json-schema-2.8.0/test/schemas/definition_schema.json 0000664 0000000 0000000 00000000407 13046321150 0022671 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"
}
}
}
json-schema-2.8.0/test/schemas/definition_schema_with_special_characters.json 0000664 0000000 0000000 00000000344 13046321150 0027623 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"
}
}
}
json-schema-2.8.0/test/schemas/extends_and_additionalProperties_false_schema.json 0000664 0000000 0000000 00000001100 13046321150 0030443 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
}
json-schema-2.8.0/test/schemas/extends_and_patternProperties_schema.json 0000664 0000000 0000000 00000001046 13046321150 0026647 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"
}
}
}
json-schema-2.8.0/test/schemas/good_schema_1.json 0000664 0000000 0000000 00000000160 13046321150 0021705 0 ustar 00root root 0000000 0000000 {
"type" : "object",
"properties" : {
"a" : {
"type" : "integer"
}
},
"required": ["a"]
}
json-schema-2.8.0/test/schemas/good_schema_2.json 0000664 0000000 0000000 00000000173 13046321150 0021712 0 ustar 00root root 0000000 0000000 {
"type" : "object",
"properties" : {
"b" : {
"$ref" : "good_schema_1.json"
}
},
"required": ["b"]
}
json-schema-2.8.0/test/schemas/good_schema_extends1.json 0000664 0000000 0000000 00000000157 13046321150 0023306 0 ustar 00root root 0000000 0000000 {
"type" : "object",
"extends": {"$ref": "good_schema_1.json"},
"properties" : {
"c" : {
}
}
}
json-schema-2.8.0/test/schemas/good_schema_extends2.json 0000664 0000000 0000000 00000000235 13046321150 0023304 0 ustar 00root root 0000000 0000000 {
"type" : "object",
"extends": [
{"$ref": "good_schema_1.json"},
{"$ref": "good_schema_2.json"}
],
"properties" : {
"c" : {
}
}
}
json-schema-2.8.0/test/schemas/inner_schema.json 0000664 0000000 0000000 00000000417 13046321150 0021655 0 ustar 00root root 0000000 0000000 {
"type": "object",
"properties": {
"innerA": {
"description": "blah",
"type":"boolean"
},
"innerB": {
"description": "blah",
"type":"boolean"
},
"innerC": {
"description": "blah",
"type": "boolean"
}
}
}
json-schema-2.8.0/test/schemas/one_of_ref_links_schema.json 0000664 0000000 0000000 00000000465 13046321150 0024046 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" }
]
}
}
}
}
json-schema-2.8.0/test/schemas/ref john with spaces schema.json 0000664 0000000 0000000 00000000306 13046321150 0024326 0 ustar 00root root 0000000 0000000 {
"$schema" : "http://json-schema.org/draft-04/schema#",
"type" : "object",
"required" : ["first"],
"properties": {
"first": {
"type": "string",
"enum": ["john"]
}
}
}
json-schema-2.8.0/test/schemas/relative_definition_schema.json 0000664 0000000 0000000 00000000232 13046321150 0024560 0 ustar 00root root 0000000 0000000 {
"$schema": "http://json-schema.org/draft-04/schema#",
"properties": {
"a": {
"$ref": "definition_schema.json#/definitions/foo"
}
}
} json-schema-2.8.0/test/schemas/self_link_schema.json 0000664 0000000 0000000 00000000421 13046321150 0022503 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"
}
}
}
json-schema-2.8.0/test/schemas/up_link_schema.json 0000664 0000000 0000000 00000000417 13046321150 0022203 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"
}
}
}
json-schema-2.8.0/test/stringify_test.rb 0000664 0000000 0000000 00000002407 13046321150 0020307 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
json-schema-2.8.0/test/support/ 0000775 0000000 0000000 00000000000 13046321150 0016416 5 ustar 00root root 0000000 0000000 json-schema-2.8.0/test/support/array_validation.rb 0000664 0000000 0000000 00000005164 13046321150 0022301 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
json-schema-2.8.0/test/support/enum_validation.rb 0000664 0000000 0000000 00000004752 13046321150 0022131 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
json-schema-2.8.0/test/support/number_validation.rb 0000664 0000000 0000000 00000003433 13046321150 0022450 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
json-schema-2.8.0/test/support/object_validation.rb 0000664 0000000 0000000 00000003456 13046321150 0022433 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
json-schema-2.8.0/test/support/strict_validation.rb 0000664 0000000 0000000 00000005365 13046321150 0022476 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
json-schema-2.8.0/test/support/string_validation.rb 0000664 0000000 0000000 00000010025 13046321150 0022461 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
json-schema-2.8.0/test/support/test_helper.rb 0000664 0000000 0000000 00000002400 13046321150 0021255 0 ustar 00root root 0000000 0000000 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
json-schema-2.8.0/test/support/type_validation.rb 0000664 0000000 0000000 00000004026 13046321150 0022140 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
json-schema-2.8.0/test/test-suite/ 0000775 0000000 0000000 00000000000 13046321150 0017010 5 ustar 00root root 0000000 0000000 json-schema-2.8.0/test/type_attribute_test.rb 0000664 0000000 0000000 00000001161 13046321150 0021331 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
json-schema-2.8.0/test/uri_parsing_test.rb 0000664 0000000 0000000 00000003241 13046321150 0020610 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
json-schema-2.8.0/test/uri_util_test.rb 0000664 0000000 0000000 00000017030 13046321150 0020123 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
json-schema-2.8.0/test/validator_schema_reader_test.rb 0000664 0000000 0000000 00000003033 13046321150 0023114 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