pax_global_header 0000666 0000000 0000000 00000000064 12643714510 0014515 g ustar 00root root 0000000 0000000 52 comment=597952b0328a1c8a82507528eb9e795a323f995e
json-schema-2.6.0/ 0000775 0000000 0000000 00000000000 12643714510 0013731 5 ustar 00root root 0000000 0000000 json-schema-2.6.0/.gitignore 0000664 0000000 0000000 00000000067 12643714510 0015724 0 ustar 00root root 0000000 0000000 /.project
.*.swp
pkg
*.gem
/Gemfile.lock
.bundle
.idea
json-schema-2.6.0/.gitmodules 0000664 0000000 0000000 00000000207 12643714510 0016105 0 ustar 00root root 0000000 0000000 [submodule "test/test-suite"]
path = test/test-suite
branch = develop
url = git://github.com/json-schema/JSON-Schema-Test-Suite.git
json-schema-2.6.0/.travis.yml 0000664 0000000 0000000 00000000632 12643714510 0016043 0 ustar 00root root 0000000 0000000 language: "ruby"
rvm:
- "1.8"
- "1.9"
- "2.0"
- "2.1"
- "2.2"
- "2.3.0"
- "jruby"
- "rbx"
sudo: false
install:
- bundle install --retry=3
matrix:
include:
- rvm: "2.3.0"
gemfile: "gemfiles/Gemfile.multi_json.x"
- rvm: "2.3.0"
gemfile: "gemfiles/Gemfile.yajl-ruby.x"
- rvm: "2.3.0"
gemfile: "gemfiles/Gemfile.uuidtools.x"
allow_failures:
- rvm: "1.8"
json-schema-2.6.0/CHANGELOG.md 0000664 0000000 0000000 00000000773 12643714510 0015551 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]
### 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.6.0/CONTRIBUTING.md 0000664 0000000 0000000 00000001576 12643714510 0016173 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.6.0/CONTRIBUTORS.md 0000664 0000000 0000000 00000001517 12643714510 0016214 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
json-schema-2.6.0/Gemfile 0000664 0000000 0000000 00000000137 12643714510 0015225 0 ustar 00root root 0000000 0000000 source "https://rubygems.org"
gemspec
gem "json", ">= 1.7", :platforms => [:mri_18, :mri_19]
json-schema-2.6.0/LICENSE.md 0000664 0000000 0000000 00000002065 12643714510 0015340 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.6.0/README.textile 0000664 0000000 0000000 00000036370 12643714510 0016277 0 ustar 00root root 0000000 0000000 !https://travis-ci.org/ruby-json-schema/json-schema.svg?branch=master!:https://travis-ci.org/ruby-json-schema/json-schema
!https://codeclimate.com/github/ruby-json-schema/json-schema/badges/gpa.svg!:https://codeclimate.com/github/ruby-json-schema/json-schema
h1. 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.
h2. Additional Resources
* "Google Groups":https://groups.google.com/forum/#!forum/ruby-json-schema
* #ruby-json-schema on chat.freenode.net
h2. 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.
h2. Installation
From rubygems.org:
gem install json-schema
From the git repo:
$ gem build json-schema.gemspec
$ gem install json-schema-2.5.2.gem
h2. Usage
Three base validation methods exist: validate, validate!, and fully_validate. The first returns a boolean on whether a validation attempt passes and the second will throw a JSON::Schema::ValidationError with an appropriate message/trace on where the validation failed. The third validation method does not immediately fail upon a validation error and instead 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.
h3. Validate Ruby objects against a Ruby schema
For further information on json schema itself refer to Understanding JSON Schema.
require 'rubygems'
require 'json-schema'
schema = {
"type" => "object",
"required" => ["a"],
"properties" => {
"a" => {"type" => "integer"}
}
}
data = {
"a" => 5
}
JSON::Validator.validate(schema, data)
h3. Validate a JSON string against a JSON schema file
require 'rubygems'
require 'json-schema'
JSON::Validator.validate('schema.json', '{"a" : 5}')
h3. Validate a list of objects against a schema that represents the individual objects
require 'rubygems'
require 'json-schema'
data = ['user','user','user']
JSON::Validator.validate('user.json', data, :list => true)
h3. Strictly validate an object's properties
With the :strict option, validation fails when an object contains properties that are not defined in the schema's property list or doesn't match the additionalProperties property. Furthermore, all properties are treated as required regardless of required properties set in the schema.
require 'rubygems'
require 'json-schema'
schema = {
"type" => "object",
"properties" => {
"a" => {"type" => "integer"},
"b" => {"type" => "integer"}
}
}
JSON::Validator.validate(schema, {"a" => 1, "b" => 2}, :strict => true) # ==> true
JSON::Validator.validate(schema, {"a" => 1, "b" => 2, "c" => 3}, :strict => true) # ==> false
JSON::Validator.validate(schema, {"a" => 1}, :strict => true) # ==> false
h3. Catch a validation error and print it out
require 'rubygems'
require 'json-schema'
schema = {
"type" => "object",
"required" => ["a"],
"properties" => {
"a" => {"type" => "integer"}
}
}
data = {
"a" => "taco"
}
begin
JSON::Validator.validate!(schema, data)
rescue JSON::Schema::ValidationError
puts $!.message
end
h3. Fully validate against a schema and catch all errors
require 'rubygems'
require 'json-schema'
schema = {
"type" => "object",
"required" => ["a","b"],
"properties" => {
"a" => {"type" => "integer"},
"b" => {"type" => "string"}
}
}
data = {
"a" => "taco"
}
errors = JSON::Validator.fully_validate(schema, data)
# ["The property '#/a' of type String did not match the following type: integer in schema 03179a21-197e-5414-9611-e9f63e8324cd#", "The property '#/' did not contain a required property of 'b' in schema 03179a21-197e-5414-9611-e9f63e8324cd#"]
h3. Fully validate against a schema and catch all errors as objects
require 'rubygems'
require 'json-schema'
schema = {
"type" => "object",
"required" => ["a","b"],
"properties" => {
"a" => {"type" => "integer"},
"b" => {"type" => "string"}
}
}
data = {
"a" => "taco"
}
errors = JSON::Validator.fully_validate(schema, data, :errors_as_objects => true)
# [{:message=>"The property '#/a' of type String did not match the following type: integer in schema 03179a21-197e-5414-9611-e9f63e8324cd#", :schema=>#, :failed_attribute=>"Type", :fragment=>"#/a"}, {:message=>"The property '#/' did not contain a required property of 'b' in schema 03179a21-197e-5414-9611-e9f63e8324cd#", :schema=>#, :failed_attribute=>"Properties", :fragment=>"#/"}]
h3. Validate against a fragment of a supplied schema
require 'rubygems'
require 'json-schema'
schema = {
"type" => "object",
"required" => ["a","b"],
"properties" => {
"a" => {"type" => "integer"},
"b" => {"type" => "string"},
"c" => {
"type" => "object",
"properties" => {
"z" => {"type" => "integer"}
}
}
}
}
data = {
"z" => 1
}
JSON::Validator.validate(schema, data, :fragment => "#/properties/c")
h3. Validate a JSON object against a JSON schema object, while also validating the schema itself
require 'rubygems'
require 'json-schema'
schema = {
"type" => "object",
"required" => ["a"],
"properties" => {
"a" => {"type" => "integer", "required" => "true"} # This will fail schema validation!
}
}
data = {
"a" => 5
}
JSON::Validator.validate(schema, data, :validate_schema => true)
h3. Validate a JSON object against a JSON schema object, while inserting default values from the schema
With the :insert_defaults option set to true any missing property that has a
default value specified in the schema will be inserted into the validated data. The inserted default value is validated hence catching a schema that specifies an invalid default value.
require 'rubygems'
require 'json-schema'
schema = {
"type" => "object",
"required" => ["a"],
"properties" => {
"a" => {"type" => "integer", "default" => 42},
"b" => {"type" => "integer"}
}
}
# Would not normally validate because "a" is missing and required by schema,
# but "default" option allows insertion of valid default.
data = {
"b" => 5
}
JSON::Validator.validate(schema, data)
# false
JSON::Validator.validate(schema, data, :insert_defaults => true)
# true
# data = {
# "a" => 42,
# "b" => 5
# }
h3. Validate an object against a JSON Schema Draft 2 schema
require 'rubygems'
require 'json-schema'
schema = {
"type" => "object",
"properties" => {
"a" => {"type" => "integer", "optional" => true}
}
}
data = {
"a" => 5
}
JSON::Validator.validate(schema, data, :version => :draft2)
h3. Explicitly specifying the type of the data
By default, json-schema accepts a variety of different types for the data parameter, and it will try to work out what to do with it dynamically. You can pass it a string uri (in which case it will download the json from that location before validating), a string of JSON text, or simply a ruby object (such as an array or hash representing parsed json). However, sometimes the nature of the data is ambiguous (for example, is "http://github.com" just a string, or is it a uri?). In other situations, you have already parsed your JSON, and you don't need to re-parse it.
If you want to be explict about what kind of data is being parsed, JSON schema supports a number of options:
require 'rubygems'
require 'json-schema'
schema = {
"type" => "string"
}
# examines the data, determines it's a uri, then tries to load data from it
JSON::Validator.validate(schema, 'https://api.github.com') # returns false
# data is already parsed json - just accept it as-is
JSON::Validator.validate(schema, 'https://api.github.com', :parse_data => false) # returns true
# data is parsed to a json string
JSON::Validator.validate(schema, '"https://api.github.com"', :json => true) # returns true
# loads data from the uri
JSON::Validator.validate(schema, 'https://api.github.com', :uri => true) # returns false
h3. Extend an existing schema and validate against it
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.
require 'rubygems'
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']}"
raise JSON::Schema::ValidationError.new(message, fragments, current_schema)
end
end
end
class ExtendedSchema < JSON::Schema::Validator
def initialize
super
extend_schema_definition("http://json-schema.org/draft-03/schema#")
@attributes["bitwise-and"] = BitwiseAndAttribute
@uri = URI.parse("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
h3. Custom format validation
The JSON schema standard allows custom formats in schema definitions which should be ignored by validators that do not support them. JSON::Schema allows registering procs as custom format validators which receive the value to be checked as parameter and must raise a JSON::Schema::CustomFormatError to indicate a format violation. The error message will be prepended by the property name, e.g. "The property '#a'":
require 'rubygems'
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"})
h2. Controlling Remote Schema Reading
In some cases, you may wish to prevent the JSON Schema library from making HTTP calls or reading local files in order to resolve $ref schemas. If you fully control all schemas which should be used by validation, this could be accomplished by registering all referenced schemas with the validator in advance:
schema = JSON::Schema.new(some_schema_definition, Addressable::URI.parse('http://example.com/my-schema'))
JSON::Validator.add_schema(schema)
If more extensive control is necessary, the JSON::Schema::Reader instance used can be configured in a few ways:
# Change the default schema reader used
JSON::Validator.schema_reader = JSON::Schema::Reader.new(:accept_uri => true, :accept_file => false)
# For this validation call, use a reader which only accepts URIs from my-website.com
schema_reader = JSON::Schema::Reader.new(
:accept_uri => proc { |uri| uri.host == 'my-website.com' }
)
JSON::Validator.validate(some_schema, some_object, :schema_reader => schema_reader)
The JSON::Schema::Reader interface requires only an object which responds to read(string) and returns a JSON::Schema instance. See the "API documentation":http://www.rubydoc.info/github/ruby-json-schema/json-schema/master/JSON/Schema/Reader for more information.
h2. JSON Backends
The JSON Schema library currently supports the json and yajl-ruby backend JSON parsers. If either of these libraries are installed, they will be automatically loaded and used to parse any JSON strings supplied by the user.
If more than one of the supported JSON backends are installed, the yajl-ruby parser is used by default. This can be changed by issuing the following before validation:
JSON::Validator.json_backend = :json
Optionally, the JSON Schema library supports using the MultiJSON library for selecting JSON backends. If the MultiJSON library is installed, it will be autoloaded.
h2. 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.6.0/Rakefile 0000664 0000000 0000000 00000001116 12643714510 0015375 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 << "."
t.warning = true
t.verbose = true
t.test_files = FileList.new('test/test*.rb') do |fl|
fl.exclude(/test_helper\.rb$/)
end
end
task :test => :update_common_tests
task :default => :test
json-schema-2.6.0/VERSION.yml 0000664 0000000 0000000 00000000033 12643714510 0015575 0 ustar 00root root 0000000 0000000 major: 2
minor: 6
patch: 0
json-schema-2.6.0/gemfiles/ 0000775 0000000 0000000 00000000000 12643714510 0015524 5 ustar 00root root 0000000 0000000 json-schema-2.6.0/gemfiles/Gemfile.multi_json.x 0000664 0000000 0000000 00000000110 12643714510 0021437 0 ustar 00root root 0000000 0000000 source "https://rubygems.org"
gemspec :path => "../"
gem "multi_json"
json-schema-2.6.0/gemfiles/Gemfile.uuidtools.x 0000664 0000000 0000000 00000000107 12643714510 0021311 0 ustar 00root root 0000000 0000000 source "https://rubygems.org"
gemspec :path => "../"
gem "uuidtools"
json-schema-2.6.0/gemfiles/Gemfile.yajl-ruby.x 0000664 0000000 0000000 00000000107 12643714510 0021200 0 ustar 00root root 0000000 0000000 source "https://rubygems.org"
gemspec :path => "../"
gem "yajl-ruby"
json-schema-2.6.0/json-schema.gemspec 0000664 0000000 0000000 00000001607 12643714510 0017511 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.textile","LICENSE.md"]
s.required_ruby_version = ">= 1.8.7"
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.3.8'
end
json-schema-2.6.0/lib/ 0000775 0000000 0000000 00000000000 12643714510 0014477 5 ustar 00root root 0000000 0000000 json-schema-2.6.0/lib/json-schema.rb 0000664 0000000 0000000 00000001525 12643714510 0017236 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.6.0/lib/json-schema/ 0000775 0000000 0000000 00000000000 12643714510 0016706 5 ustar 00root root 0000000 0000000 json-schema-2.6.0/lib/json-schema/attribute.rb 0000664 0000000 0000000 00000002241 12643714510 0021235 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
end
end
end
json-schema-2.6.0/lib/json-schema/attributes/ 0000775 0000000 0000000 00000000000 12643714510 0021074 5 ustar 00root root 0000000 0000000 json-schema-2.6.0/lib/json-schema/attributes/additionalitems.rb 0000664 0000000 0000000 00000002064 12643714510 0024575 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.6.0/lib/json-schema/attributes/additionalproperties.rb 0000664 0000000 0000000 00000004471 12643714510 0025654 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[key] || 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.6.0/lib/json-schema/attributes/allof.rb 0000664 0000000 0000000 00000003107 12643714510 0022517 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 #{data.class} 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.6.0/lib/json-schema/attributes/anyof.rb 0000664 0000000 0000000 00000003467 12643714510 0022547 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 #{data.class} 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.6.0/lib/json-schema/attributes/dependencies.rb 0000664 0000000 0000000 00000003231 12643714510 0024046 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.6.0/lib/json-schema/attributes/disallow.rb 0000664 0000000 0000000 00000000606 12643714510 0023241 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.6.0/lib/json-schema/attributes/divisibleby.rb 0000664 0000000 0000000 00000001271 12643714510 0023727 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.6.0/lib/json-schema/attributes/enum.rb 0000664 0000000 0000000 00000001366 12643714510 0022373 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.6.0/lib/json-schema/attributes/extends.rb 0000664 0000000 0000000 00000003343 12643714510 0023076 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
s = {'$ref' => s} if s.is_a?(String)
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.6.0/lib/json-schema/attributes/format.rb 0000664 0000000 0000000 00000001000 12643714510 0022700 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.6.0/lib/json-schema/attributes/formats/ 0000775 0000000 0000000 00000000000 12643714510 0022547 5 ustar 00root root 0000000 0000000 json-schema-2.6.0/lib/json-schema/attributes/formats/custom.rb 0000664 0000000 0000000 00000001247 12643714510 0024412 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.6.0/lib/json-schema/attributes/formats/date.rb 0000664 0000000 0000000 00000001542 12643714510 0024013 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.6.0/lib/json-schema/attributes/formats/date_time.rb 0000664 0000000 0000000 00000003276 12643714510 0025037 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.6.0/lib/json-schema/attributes/formats/date_time_v4.rb 0000664 0000000 0000000 00000001041 12643714510 0025434 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.6.0/lib/json-schema/attributes/formats/ip.rb 0000664 0000000 0000000 00000002021 12643714510 0023477 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.6.0/lib/json-schema/attributes/formats/time.rb 0000664 0000000 0000000 00000002003 12643714510 0024025 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.6.0/lib/json-schema/attributes/formats/uri.rb 0000664 0000000 0000000 00000001132 12643714510 0023670 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.6.0/lib/json-schema/attributes/items.rb 0000664 0000000 0000000 00000001452 12643714510 0022544 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|
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.6.0/lib/json-schema/attributes/limit.rb 0000664 0000000 0000000 00000007704 12643714510 0022547 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.6.0/lib/json-schema/attributes/maxdecimal.rb 0000664 0000000 0000000 00000001223 12643714510 0023523 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.6.0/lib/json-schema/attributes/multipleof.rb 0000664 0000000 0000000 00000000306 12643714510 0023600 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.6.0/lib/json-schema/attributes/not.rb 0000664 0000000 0000000 00000002145 12643714510 0022223 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 #{data.class} 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.6.0/lib/json-schema/attributes/oneof.rb 0000664 0000000 0000000 00000003576 12643714510 0022542 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 #{data.class} did not match any of the required schemas"
else
message = "The property '#{build_fragment(fragments)}' of type #{data.class} 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.6.0/lib/json-schema/attributes/pattern.rb 0000664 0000000 0000000 00000001163 12643714510 0023077 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.6.0/lib/json-schema/attributes/patternproperties.rb 0000664 0000000 0000000 00000001345 12643714510 0025216 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.6.0/lib/json-schema/attributes/properties.rb 0000664 0000000 0000000 00000005166 12643714510 0023625 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.6.0/lib/json-schema/attributes/properties_optional.rb 0000664 0000000 0000000 00000001717 12643714510 0025530 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.6.0/lib/json-schema/attributes/ref.rb 0000664 0000000 0000000 00000005551 12643714510 0022203 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.parse(s['$ref'])
temp_uri.defer_validation do
if temp_uri.relative?
temp_uri.merge!(current_schema.uri)
# Check for absolute path
path, fragment = s['$ref'].split("#")
if path.nil? || path == ''
temp_uri.path = current_schema.uri.path
elsif path[0,1] == "/"
temp_uri.path = Pathname.new(path).cleanpath.to_s
else
temp_uri.join!(path)
end
temp_uri.fragment = fragment
end
temp_uri.fragment = "" if temp_uri.fragment.nil? || temp_uri.fragment.empty?
end
# 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 = temp_uri.fragment.split("/")
fragment_path = ''
fragments.each do |fragment|
if fragment && fragment != ''
fragment = JSON::Util::URI.unescaped_uri(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.6.0/lib/json-schema/attributes/required.rb 0000664 0000000 0000000 00000002030 12643714510 0023234 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.6.0/lib/json-schema/attributes/type.rb 0000664 0000000 0000000 00000006431 12643714510 0022406 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
# 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.6.0/lib/json-schema/attributes/type_v4.rb 0000664 0000000 0000000 00000001602 12643714510 0023012 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),
data.class,
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.6.0/lib/json-schema/attributes/uniqueitems.rb 0000664 0000000 0000000 00000000776 12643714510 0024003 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.6.0/lib/json-schema/errors/ 0000775 0000000 0000000 00000000000 12643714510 0020222 5 ustar 00root root 0000000 0000000 json-schema-2.6.0/lib/json-schema/errors/custom_format_error.rb 0000664 0000000 0000000 00000000131 12643714510 0024635 0 ustar 00root root 0000000 0000000 module JSON
class Schema
class CustomFormatError < StandardError
end
end
end
json-schema-2.6.0/lib/json-schema/errors/json_load_error.rb 0000664 0000000 0000000 00000000125 12643714510 0023726 0 ustar 00root root 0000000 0000000 module JSON
class Schema
class JsonLoadError < StandardError
end
end
end
json-schema-2.6.0/lib/json-schema/errors/json_parse_error.rb 0000664 0000000 0000000 00000000126 12643714510 0024122 0 ustar 00root root 0000000 0000000 module JSON
class Schema
class JsonParseError < StandardError
end
end
end
json-schema-2.6.0/lib/json-schema/errors/schema_error.rb 0000664 0000000 0000000 00000000123 12643714510 0023214 0 ustar 00root root 0000000 0000000 module JSON
class Schema
class SchemaError < StandardError
end
end
end
json-schema-2.6.0/lib/json-schema/errors/schema_parse_error.rb 0000664 0000000 0000000 00000000163 12643714510 0024412 0 ustar 00root root 0000000 0000000 require 'json/common'
module JSON
class Schema
class SchemaParseError < JSON::ParserError
end
end
end
json-schema-2.6.0/lib/json-schema/errors/uri_error.rb 0000664 0000000 0000000 00000000120 12643714510 0022550 0 ustar 00root root 0000000 0000000 module JSON
class Schema
class UriError < StandardError
end
end
end
json-schema-2.6.0/lib/json-schema/errors/validation_error.rb 0000664 0000000 0000000 00000003137 12643714510 0024116 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.6.0/lib/json-schema/schema.rb 0000664 0000000 0000000 00000003276 12643714510 0020503 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(@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?
JSON::Schema.new(array_schema, uri, validator)
end
def to_s
@schema.to_json
end
end
end
json-schema-2.6.0/lib/json-schema/schema/ 0000775 0000000 0000000 00000000000 12643714510 0020146 5 ustar 00root root 0000000 0000000 json-schema-2.6.0/lib/json-schema/schema/reader.rb 0000664 0000000 0000000 00000007223 12643714510 0021741 0 ustar 00root root 0000000 0000000 require 'open-uri'
require 'pathname'
module JSON
class Schema
# Raised by {JSON::Schema::Reader} when one of its settings indicate
# a schema should not be readed.
class ReadRefused < 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("Read of #{type == :uri ? 'URI' : type} at #{location} refused!")
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
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
end
def read_file(pathname)
if accept_file?(pathname)
File.read(JSON::Util::URI.unescaped_uri(pathname.to_s))
else
raise JSON::Schema::ReadRefused.new(pathname.to_s, :file)
end
end
end
end
end
json-schema-2.6.0/lib/json-schema/schema/validator.rb 0000664 0000000 0000000 00000001751 12643714510 0022464 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)
validator = JSON::Validator.validator_for(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.6.0/lib/json-schema/util/ 0000775 0000000 0000000 00000000000 12643714510 0017663 5 ustar 00root root 0000000 0000000 json-schema-2.6.0/lib/json-schema/util/array_set.rb 0000664 0000000 0000000 00000001005 12643714510 0022175 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_fixnum(x) }
end
@values.include?(convert_to_float_if_fixnum(obj))
end
private
def convert_to_float_if_fixnum(value)
value.is_a?(Fixnum) ? value.to_f : value
end
end
json-schema-2.6.0/lib/json-schema/util/uri.rb 0000664 0000000 0000000 00000003202 12643714510 0021004 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.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.unescaped_uri(uri)
parsed_uri = parse(uri)
Addressable::URI.unescape(parsed_uri.path)
end
end
end
end
json-schema-2.6.0/lib/json-schema/util/uuid.rb 0000664 0000000 0000000 00000020520 12643714510 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
# Typically a Bignum instance, but can be a Fixnum.
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.6.0/lib/json-schema/validator.rb 0000664 0000000 0000000 00000046537 12643714510 0021237 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 = false
@@default_opts = {
:list => false,
:version => nil,
:validate_schema => false,
:record_errors => false,
:errors_as_objects => false,
:insert_defaults => false,
:clear_cache => true,
: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 = JSON::Validator.validator_for_name(@options[:version])
@options[:version] = validator
@options[:schema_reader] ||= JSON::Validator.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] = false if @options[:clear_cache] == false
@@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 = JSON::Validator.validator_for_name(@base_schema.schema["$schema"])
end
metaschema = base_validator ? base_validator.metaschema : validator.metaschema
# Don't clear the cache during metaschema validation!
meta_validator = JSON::Validator.new(metaschema, @base_schema.schema, {:clear_cache => false})
meta_validator.validate
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[:errors_as_objects]
return @errors.map{|e| e.to_hash}
else
return @errors.map{|e| e.to_string}
end
ensure
if @validation_options[:clear_cache] == true
Validator.clear_cache
end
if @validation_options[:insert_defaults]
JSON::Validator.merge_missing_values(@data, @original_data)
end
end
def load_ref_schema(parent_schema, ref)
schema_uri = absolutize_ref_uri(ref, parent_schema.uri)
return true if self.class.schema_loaded?(schema_uri)
schema = @options[:schema_reader].read(schema_uri)
self.class.add_schema(schema)
build_schemas(schema)
end
def absolutize_ref_uri(ref, parent_schema_uri)
ref_uri = JSON::Util::URI.strip_fragment(ref)
return ref_uri if ref_uri.absolute?
# This is a self reference and thus the schema does not need to be re-loaded
return parent_schema_uri if ref_uri.path.empty?
uri = JSON::Util::URI.strip_fragment(parent_schema_uri.dup)
Util::URI.normalized_uri(uri.join(ref_uri.path))
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']
Validator.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
validator = JSON::Validator.new(schema, data, opts)
validator.validate
return true
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 = JSON::Validator.new(schema, data, opts)
validator.validate
return true
end
alias_method 'validate2', 'validate!'
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={})
opts[:record_errors] = true
validator = JSON::Validator.new(schema, data, opts)
validator.validate
end
def fully_validate_schema(schema, opts={})
data = schema
schema = JSON::Validator.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 = {} if @@cache_schemas == false
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)
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 JSON::Schema::SchemaError.new("Schema not found: #{schema_uri}")
else
validator
end
end
def validator_for_name(schema_name)
return default_validator unless schema_name
validator = validators_for_names([schema_name]).first
if validator.nil?
raise JSON::Schema::SchemaError.new("The requested JSON schema version is not supported")
else
validator
end
end
alias_method :validator_for, :validator_for_uri
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 = ["draft1", "draft2", "draft3", "draft4", nil])
custom_format_validator = JSON::Schema::CustomFormat.new(validation_proc)
validators_for_names(versions).each do |validator|
validator.formats[format.to_s] = custom_format_validator
end
end
def deregister_format_validator(format, versions = ["draft1", "draft2", "draft3", "draft4", nil])
validators_for_names(versions).each do |validator|
validator.formats[format.to_s] = validator.default_formats[format.to_s]
end
end
def restore_default_formats(versions = ["draft1", "draft2", "draft3", "draft4", nil])
validators_for_names(versions).each do |validator|
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
private
def validators_for_names(names)
names = names.map { |name| name.to_s }
[].tap do |memo|
validators.each do |_, validator|
if (validator.names & names).any?
memo << validator
end
end
if names.include?('')
memo << default_validator
end
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(JSON::Validator.parse(schema), schema_uri, @options[:version])
if @options[:list] && @options[:fragment].nil?
schema = schema.to_array_schema
end
Validator.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
Validator.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)))
Validator.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
Validator.add_schema(schema)
else
raise 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 = JSON::Validator.parse(data)
elsif @options[:uri]
json_uri = Util::URI.normalized_uri(data)
data = JSON::Validator.parse(custom_open(json_uri))
elsif data.is_a?(String)
begin
data = JSON::Validator.parse(data)
rescue JSON::Schema::JsonParseError
begin
json_uri = Util::URI.normalized_uri(data)
data = JSON::Validator.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_uri(uri))
rescue SystemCallError => e
raise JSON::Schema::JsonLoadError, e.message
end
end
end
end
end
json-schema-2.6.0/lib/json-schema/validators/ 0000775 0000000 0000000 00000000000 12643714510 0021056 5 ustar 00root root 0000000 0000000 json-schema-2.6.0/lib/json-schema/validators/draft1.rb 0000664 0000000 0000000 00000003124 12643714510 0022564 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.6.0/lib/json-schema/validators/draft2.rb 0000664 0000000 0000000 00000003225 12643714510 0022567 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.6.0/lib/json-schema/validators/draft3.rb 0000664 0000000 0000000 00000003651 12643714510 0022573 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.6.0/lib/json-schema/validators/draft4.rb 0000664 0000000 0000000 00000004453 12643714510 0022575 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.6.0/lib/json-schema/validators/hyper-draft1.rb 0000664 0000000 0000000 00000000404 12643714510 0023707 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.6.0/lib/json-schema/validators/hyper-draft2.rb 0000664 0000000 0000000 00000000404 12643714510 0023710 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.6.0/lib/json-schema/validators/hyper-draft4.rb 0000664 0000000 0000000 00000000404 12643714510 0023712 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.6.0/resources/ 0000775 0000000 0000000 00000000000 12643714510 0015743 5 ustar 00root root 0000000 0000000 json-schema-2.6.0/resources/draft-01.json 0000664 0000000 0000000 00000004713 12643714510 0020161 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.6.0/resources/draft-02.json 0000664 0000000 0000000 00000005244 12643714510 0020162 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.6.0/resources/draft-03.json 0000664 0000000 0000000 00000005214 12643714510 0020160 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.6.0/resources/draft-04.json 0000664 0000000 0000000 00000010427 12643714510 0020163 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.6.0/test/ 0000775 0000000 0000000 00000000000 12643714510 0014710 5 ustar 00root root 0000000 0000000 json-schema-2.6.0/test/data/ 0000775 0000000 0000000 00000000000 12643714510 0015621 5 ustar 00root root 0000000 0000000 json-schema-2.6.0/test/data/all_of_ref_data.json 0000664 0000000 0000000 00000000026 12643714510 0021573 0 ustar 00root root 0000000 0000000 {
"name" : "john"
}
json-schema-2.6.0/test/data/any_of_ref_data.json 0000664 0000000 0000000 00000000076 12643714510 0021617 0 ustar 00root root 0000000 0000000 {
"names" :
[ "john"
, "jane"
, "jimmy"
]
}
json-schema-2.6.0/test/data/bad_data_1.json 0000664 0000000 0000000 00000000022 12643714510 0020445 0 ustar 00root root 0000000 0000000 {
"a" : "poop"
} json-schema-2.6.0/test/data/good_data_1.json 0000664 0000000 0000000 00000000015 12643714510 0020651 0 ustar 00root root 0000000 0000000 {
"a" : 5
} json-schema-2.6.0/test/data/one_of_ref_links_data.json 0000664 0000000 0000000 00000000233 12643714510 0023004 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.6.0/test/schemas/ 0000775 0000000 0000000 00000000000 12643714510 0016333 5 ustar 00root root 0000000 0000000 json-schema-2.6.0/test/schemas/address_microformat.json 0000664 0000000 0000000 00000001200 12643714510 0023246 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.6.0/test/schemas/all_of_ref_base_schema.json 0000664 0000000 0000000 00000000121 12643714510 0023622 0 ustar 00root root 0000000 0000000 {
"type": "object",
"properties" : {
"name" : { "type": "integer" }
}
}
json-schema-2.6.0/test/schemas/all_of_ref_schema.json 0000664 0000000 0000000 00000000220 12643714510 0022630 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.6.0/test/schemas/any_of_ref_jane_schema.json 0000664 0000000 0000000 00000000143 12643714510 0023650 0 ustar 00root root 0000000 0000000 { "$schema" : "http://json-schema.org/draft-04/schema#"
, "type" : "string"
, "pattern" : "jane"
}
json-schema-2.6.0/test/schemas/any_of_ref_jimmy_schema.json 0000664 0000000 0000000 00000000144 12643714510 0024061 0 ustar 00root root 0000000 0000000 { "$schema" : "http://json-schema.org/draft-04/schema#"
, "type" : "string"
, "pattern" : "jimmy"
}
json-schema-2.6.0/test/schemas/any_of_ref_john_schema.json 0000664 0000000 0000000 00000000143 12643714510 0023671 0 ustar 00root root 0000000 0000000 { "$schema" : "http://json-schema.org/draft-04/schema#"
, "type" : "string"
, "pattern" : "john"
}
json-schema-2.6.0/test/schemas/any_of_ref_schema.json 0000664 0000000 0000000 00000000542 12643714510 0022656 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.6.0/test/schemas/definition_schema.json 0000664 0000000 0000000 00000000407 12643714510 0022677 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.6.0/test/schemas/extends_and_additionalProperties-1-filename.schema.json 0000664 0000000 0000000 00000001306 12643714510 0031142 0 ustar 00root root 0000000 0000000 {
"$schema": "http://json-schema.org/draft-03/schema#",
"type": "object",
"extends": "inner.schema.json",
"properties": {
"outerA": {
"description": "blah",
"required": false,
"additionalProperties": false,
"properties": {
"outerA1": {
"type":"boolean",
"required": false
}
}
},
"outerB": {
"required": false,
"type": "array",
"minItems": 1,
"maxItems": 50,
"items": {
"extends": "inner.schema.json",
"additionalProperties": false
}
},
"outerC": {
"description": "blah",
"type":"boolean",
"required": false
}
},
"additionalProperties": false
}
json-schema-2.6.0/test/schemas/extends_and_additionalProperties-1-ref.schema.json 0000664 0000000 0000000 00000001332 12643714510 0030135 0 ustar 00root root 0000000 0000000 {
"$schema": "http://json-schema.org/draft-03/schema#",
"type": "object",
"extends": {"$ref":"inner.schema.json#"},
"properties": {
"outerA": {
"description": "blah",
"required": false,
"additionalProperties": false,
"properties": {
"outerA1": {
"type":"boolean",
"required": false
}
}
},
"outerB": {
"required": false,
"type": "array",
"minItems": 1,
"maxItems": 50,
"items": {
"extends": {"$ref":"inner.schema.json#"},
"additionalProperties": false
}
},
"outerC": {
"description": "blah",
"type":"boolean",
"required": false
}
},
"additionalProperties": false
}
json-schema-2.6.0/test/schemas/extends_and_additionalProperties-2-filename.schema.json 0000664 0000000 0000000 00000001257 12643714510 0031150 0 ustar 00root root 0000000 0000000 {
"$schema": "http://json-schema.org/draft-03/schema#",
"type": "object",
"extends": "inner.schema.json",
"additionalProperties": {
"outerA": {
"description": "blah",
"required": false,
"additionalProperties": false,
"properties": {
"outerA1": {
"type":"boolean",
"required": false
}
}
},
"outerB": {
"required": false,
"type": "array",
"minItems": 1,
"maxItems": 50,
"items": {
"extends": "inner.schema.json",
"additionalProperties": false
}
},
"outerC": {
"description": "blah",
"type":"boolean",
"required": false
}
}
}
json-schema-2.6.0/test/schemas/extends_and_additionalProperties-2-ref.schema.json 0000664 0000000 0000000 00000001303 12643714510 0030134 0 ustar 00root root 0000000 0000000 {
"$schema": "http://json-schema.org/draft-03/schema#",
"type": "object",
"extends": {"$ref":"inner.schema.json#"},
"additionalProperties": {
"outerA": {
"description": "blah",
"required": false,
"additionalProperties": false,
"properties": {
"outerA1": {
"type":"boolean",
"required": false
}
}
},
"outerB": {
"required": false,
"type": "array",
"minItems": 1,
"maxItems": 50,
"items": {
"extends": {"$ref":"inner.schema.json#"},
"additionalProperties": false
}
},
"outerC": {
"description": "blah",
"type":"boolean",
"required": false
}
}
}
json-schema-2.6.0/test/schemas/good_schema_1.json 0000664 0000000 0000000 00000000254 12643714510 0021717 0 ustar 00root root 0000000 0000000 {
"$schema" : "http://json-schema.org/draft-03/schema#",
"type" : "object",
"properties" : {
"a" : {
"type" : "integer",
"required" : true
}
}
} json-schema-2.6.0/test/schemas/good_schema_2.json 0000664 0000000 0000000 00000000270 12643714510 0021716 0 ustar 00root root 0000000 0000000 {
"$schema" : "http://json-schema.org/draft-03/schema#",
"type" : "object",
"properties" : {
"b" : {
"required" : true,
"$ref" : "good_schema_1.json"
}
}
}
json-schema-2.6.0/test/schemas/good_schema_extends1.json 0000664 0000000 0000000 00000000301 12643714510 0023303 0 ustar 00root root 0000000 0000000 {
"$schema" : "http://json-schema.org/draft-03/schema#",
"type" : "object",
"extends": {"$ref": "good_schema_1.json"},
"properties" : {
"c" : {
"required" : false
}
}
}
json-schema-2.6.0/test/schemas/good_schema_extends2.json 0000664 0000000 0000000 00000000357 12643714510 0023317 0 ustar 00root root 0000000 0000000 {
"$schema" : "http://json-schema.org/draft-03/schema#",
"type" : "object",
"extends": [
{"$ref": "good_schema_1.json"},
{"$ref": "good_schema_2.json"}
],
"properties" : {
"c" : {
"required" : false
}
}
}
json-schema-2.6.0/test/schemas/inner.schema.json 0000664 0000000 0000000 00000000622 12643714510 0021600 0 ustar 00root root 0000000 0000000 {
"$schema": "http://json-schema.org/draft-03/schema#",
"type": "object",
"properties": {
"innerA": {
"description": "blah",
"type":"boolean",
"required": false
},
"innerB": {
"description": "blah",
"type":"boolean",
"required": false
},
"innerC": {
"description": "blah",
"required": false,
"type": "boolean"
}
}
}
json-schema-2.6.0/test/schemas/one_of_ref_links_schema.json 0000664 0000000 0000000 00000000465 12643714510 0024054 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.6.0/test/schemas/ref john with spaces schema.json 0000664 0000000 0000000 00000000306 12643714510 0024334 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.6.0/test/schemas/relative_definition_schema.json 0000664 0000000 0000000 00000000232 12643714510 0024566 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.6.0/test/schemas/self_link_schema.json 0000664 0000000 0000000 00000000421 12643714510 0022511 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.6.0/test/schemas/up_link_schema.json 0000664 0000000 0000000 00000000417 12643714510 0022211 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.6.0/test/support/ 0000775 0000000 0000000 00000000000 12643714510 0016424 5 ustar 00root root 0000000 0000000 json-schema-2.6.0/test/support/array_validation.rb 0000664 0000000 0000000 00000004756 12643714510 0022315 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']
refute_valid schema, []
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']
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.6.0/test/support/enum_validation.rb 0000664 0000000 0000000 00000004752 12643714510 0022137 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.6.0/test/support/number_validation.rb 0000664 0000000 0000000 00000003762 12643714510 0022463 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
def test_multiple_of_zero
schema = {
'properties' => {
'a' => { multiple_of => 0 }
}
}
refute_valid schema, {'a' => 5}
refute_valid schema, {'a' => 0}
end
end
end
json-schema-2.6.0/test/support/object_validation.rb 0000664 0000000 0000000 00000003456 12643714510 0022441 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.6.0/test/support/strict_validation.rb 0000664 0000000 0000000 00000005463 12643714510 0022503 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 = {
"$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
end
json-schema-2.6.0/test/support/string_validation.rb 0000664 0000000 0000000 00000010025 12643714510 0022467 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.6.0/test/support/type_validation.rb 0000664 0000000 0000000 00000004026 12643714510 0022146 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.6.0/test/test-suite/ 0000775 0000000 0000000 00000000000 12643714510 0017016 5 ustar 00root root 0000000 0000000 json-schema-2.6.0/test/test_all_of_ref_schema.rb 0000664 0000000 0000000 00000002233 12643714510 0021704 0 ustar 00root root 0000000 0000000 require File.expand_path('../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 Hash 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.6.0/test/test_any_of_ref_schema.rb 0000664 0000000 0000000 00000003064 12643714510 0021726 0 ustar 00root root 0000000 0000000 require File.expand_path('../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.6.0/test/test_bad_schema_ref.rb 0000664 0000000 0000000 00000001554 12643714510 0021203 0 ustar 00root root 0000000 0000000 require File.expand_path('../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]
assert_raises(Errno::ENOENT) do
JSON::Validator.validate(schema,data)
end
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]
assert_raises(SocketError, OpenURI::HTTPError) do
JSON::Validator.validate(schema,data)
end
end
end
json-schema-2.6.0/test/test_common_test_suite.rb 0000664 0000000 0000000 00000004352 12643714510 0022040 0 ustar 00root root 0000000 0000000 require File.expand_path('../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"
],
"draft4/optional/format.json" => [
"validation of URIs",
"validation of e-mail addresses",
"validation of host names"
]
})
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.6.0/test/test_custom_format.rb 0000664 0000000 0000000 00000012401 12643714510 0021154 0 ustar 00root root 0000000 0000000 # encoding: utf-8
require File.expand_path('../test_helper', __FILE__)
class JSONSchemaCustomFormatTest < Minitest::Test
def setup
@all_versions = ['draft1', 'draft2', 'draft3', 'draft4', nil]
@format_proc = lambda { |value| raise JSON::Schema::CustomFormatError.new("must be 42") unless value == "42" }
@schema_4 = {
"$schema" => "http://json-schema.org/draft-04/schema#",
"properties" => {
"a" => {
"type" => "string",
"format" => "custom",
},
}
}
@schema_3 = @schema_4.clone
@schema_3["$schema"] = "http://json-schema.org/draft-03/schema#"
@schema_2 = @schema_4.clone
@schema_2["$schema"] = "http://json-schema.org/draft-02/schema#"
@schema_1 = @schema_4.clone
@schema_1["$schema"] = "http://json-schema.org/draft-01/schema#"
@default = @schema_4.clone
@default.delete("$schema")
@schemas = {
"draft1" => @schema_1,
"draft2" => @schema_2,
"draft3" => @schema_3,
"draft4" => @schema_4,
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(errors.count == 1 && errors.first.match(/The property '#\/a' must be 42 in schema/), "#{prefix} records fromat error")
data["a"] = 23
errors = JSON::Validator.fully_validate(schema, data)
assert(errors.count == 1 && errors.first.match(/The property '#\/a' of type (?:integer|Fixnum) did not match the following type: string/), "#{prefix} records no fromat 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.6.0/test/test_definition.rb 0000664 0000000 0000000 00000000616 12643714510 0020427 0 ustar 00root root 0000000 0000000 require File.expand_path('../test_helper', __FILE__)
class RelativeDefinitionTest < Minitest::Test
def test_definition_schema
assert_valid schema_fixture_path('definition_schema.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.6.0/test/test_extended_schema.rb 0000664 0000000 0000000 00000003453 12643714510 0021421 0 ustar 00root root 0000000 0000000 require File.expand_path('../test_helper', __FILE__)
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::Validator
def initialize
super
extend_schema_definition("http://json-schema.org/draft-03/schema#")
@attributes["bitwise-and"] = BitwiseAndAttribute
@uri = Addressable::URI.parse("http://test.com/test.json")
end
JSON::Validator.register_validator(self.new)
end
class TestExtendedSchema < Minitest::Test
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 = {
"$schema" => "http://json-schema.org/draft-03/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.6.0/test/test_extends_and_additionalProperties.rb 0000664 0000000 0000000 00000003370 12643714510 0025040 0 ustar 00root root 0000000 0000000 require File.expand_path('../test_helper', __FILE__)
class ExtendsNestedTest < Minitest::Test
def assert_validity(valid, schema_name, data, msg)
msg = "Schema should be #{valid ? :valid : :invalid}.\n(#{schema_name}) #{msg}"
schema = schema_fixture_path("#{schema_name}.schema.json")
errors = JSON::Validator.fully_validate(schema, data)
if valid
assert_equal([], errors, msg)
else
refute_equal([], errors, msg)
end
end
%w[
extends_and_additionalProperties-1-filename
extends_and_additionalProperties-1-ref
extends_and_additionalProperties-2-filename
extends_and_additionalProperties-2-ref
].each do |schema_name|
test_prefix = 'test_' + schema_name.gsub('-','_')
class_eval <<-EOB
def #{test_prefix}_valid_outer
assert_validity true, '#{schema_name}', {"outerC"=>true}, "Outer defn is broken, maybe the outer extends overrode it"
end
def #{test_prefix}_valid_outer_extended
assert_validity true, '#{schema_name}', {"innerA"=>true}, "Extends at the root level isn't working"
end
def #{test_prefix}_valid_inner
assert_validity true, '#{schema_name}', {"outerB"=>[{"innerA"=>true}]}, "Extends isn't working in the array element defn"
end
def #{test_prefix}_invalid_inner
assert_validity false, '#{schema_name}', {"outerB"=>[{"whaaaaat"=>true}]}, "Array element defn allowing anything when it should only allow what's in inner.schema"
end
EOB
if schema_name['extends_and_additionalProperties-1']
class_eval <<-EOB
def #{test_prefix}_invalid_outer
assert_validity false, '#{schema_name}', {"whaaaaat"=>true}, "Outer defn allowing anything when it shouldn't"
end
EOB
end
end
end
json-schema-2.6.0/test/test_files_v3.rb 0000664 0000000 0000000 00000003251 12643714510 0020007 0 ustar 00root root 0000000 0000000 require File.expand_path('../test_helper', __FILE__)
class JSONSchemaTest < 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
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
if JSON::Validator.json_backend != nil
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
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.6.0/test/test_fragment_resolution.rb 0000664 0000000 0000000 00000001431 12643714510 0022361 0 ustar 00root root 0000000 0000000 require File.expand_path('../test_helper', __FILE__)
class FragmentResolution < 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.6.0/test/test_fragment_validation_with_ref.rb 0000664 0000000 0000000 00000001463 12643714510 0024204 0 ustar 00root root 0000000 0000000 require File.expand_path('../test_helper', __FILE__)
class FragmentValidationWithRef < 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.6.0/test/test_full_validation.rb 0000664 0000000 0000000 00000013073 12643714510 0021454 0 ustar 00root root 0000000 0000000 require File.expand_path('../test_helper', __FILE__)
class JSONFullValidation < Minitest::Test
def test_full_validation
data = {"b" => {"a" => 5}}
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"type" => "object",
"properties" => {
"b" => {
"required" => true
}
}
}
errors = JSON::Validator.fully_validate(schema,data)
assert(errors.empty?)
data = {"c" => 5}
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"type" => "object",
"properties" => {
"b" => {
"required" => true
},
"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 = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"type" => "object",
"properties" => {
"b" => {
"type" => ["null","integer"]
}
}
}
errors = JSON::Validator.fully_validate(schema,data)
assert(errors.empty?)
schema = {
"$schema" => "http://json-schema.org/draft-03/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 = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"type" => "object",
"properties" => {
"b" => {
"required" => true
}
}
}
errors = JSON::Validator.fully_validate(schema,data,:errors_as_objects => true)
assert(errors.empty?)
data = {"c" => 5}
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"type" => "object",
"properties" => {
"b" => {
"required" => true
},
"c" => {
"type" => "string"
}
}
}
errors = JSON::Validator.fully_validate(schema,data,:errors_as_objects => true)
assert(errors.length == 2)
assert(errors[0][:failed_attribute] == "Properties")
assert(errors[0][:fragment] == "#/")
assert(errors[1][:failed_attribute] == "Type")
assert(errors[1][:fragment] == "#/c")
end
def test_full_validation_with_nested_required_properties
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"type" => "object",
"properties" => {
"x" => {
"required" => true,
"type" => "object",
"properties" => {
"a" => {"type"=>"integer","required"=>true},
"b" => {"type"=>"integer","required"=>true},
"c" => {"type"=>"integer","required"=>false},
"d" => {"type"=>"integer","required"=>false},
"e" => {"type"=>"integer","required"=>false},
}
}
}
}
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 'Properties', errors[0][:failed_attribute]
assert_equal '#/x/e', errors[1][:fragment]
assert_equal 'Type', errors[1][:failed_attribute]
end
def test_full_validation_with_nested_required_propertiesin_array
schema = {
"$schema" => "http://json-schema.org/draft-03/schema#",
"type" => "object",
"properties" => {
"x" => {
"required" => true,
"type" => "array",
"items" => {
"type" => "object",
"properties" => {
"a" => {"type"=>"integer","required"=>true},
"b" => {"type"=>"integer","required"=>true},
"c" => {"type"=>"integer","required"=>false},
"d" => {"type"=>"integer","required"=>false},
"e" => {"type"=>"integer","required"=>false},
}
}
}
}
}
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 'Properties', errors[0][:failed_attribute]
assert_equal '#/x/1/e', errors[1][:fragment]
assert_equal 'Type', errors[1][:failed_attribute]
end
end
json-schema-2.6.0/test/test_helper.rb 0000664 0000000 0000000 00000002213 12643714510 0017551 0 ustar 00root root 0000000 0000000 require 'minitest/autorun'
require 'webmock/minitest'
$:.unshift(File.expand_path('../../lib', __FILE__))
require 'json-schema'
Dir[File.join(File.expand_path('../support', __FILE__), '*.rb')].each do |support_file|
require support_file
end
class Minitest::Test
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 = {})
if !options.key?(:version) && respond_to?(:schema_version)
options = options.merge(:version => schema_version)
end
errors = JSON::Validator.fully_validate(schema, data, options)
assert_equal([], errors, "#{data.inspect} should be valid for schema:\n#{schema.inspect}")
end
def refute_valid(schema, data, options = {})
if !options.key?(:version) && respond_to?(:schema_version)
options = options.merge(:version => schema_version)
end
errors = JSON::Validator.fully_validate(schema, data, options)
refute_equal([], errors, "#{data.inspect} should be invalid for schema:\n#{schema.inspect}")
end
end
json-schema-2.6.0/test/test_initialize_data.rb 0000664 0000000 0000000 00000007360 12643714510 0021434 0 ustar 00root root 0000000 0000000 require File.expand_path('../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::JsonLoadError) { 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.6.0/test/test_jsonschema_draft1.rb 0000664 0000000 0000000 00000005467 12643714510 0021703 0 ustar 00root root 0000000 0000000 require File.expand_path('../test_helper', __FILE__)
class JSONSchemaDraft1Test < Minitest::Test
def schema_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.6.0/test/test_jsonschema_draft2.rb 0000664 0000000 0000000 00000004706 12643714510 0021677 0 ustar 00root root 0000000 0000000 require File.expand_path('../test_helper', __FILE__)
class JSONSchemaDraft2Test < Minitest::Test
def schema_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.6.0/test/test_jsonschema_draft3.rb 0000664 0000000 0000000 00000030111 12643714510 0021665 0 ustar 00root root 0000000 0000000 # encoding: utf-8
require File.expand_path('../test_helper', __FILE__)
class JSONSchemaDraft3Test < Minitest::Test
def schema_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.6.0/test/test_jsonschema_draft4.rb 0000664 0000000 0000000 00000041061 12643714510 0021674 0 ustar 00root root 0000000 0000000 # encoding: utf-8
require File.expand_path('../test_helper', __FILE__)
class JSONSchemaDraft4Test < Minitest::Test
def schema_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_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.6.0/test/test_list_option.rb 0000664 0000000 0000000 00000001113 12643714510 0020633 0 ustar 00root root 0000000 0000000 require File.expand_path('../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
data = [{"a" => 1}]
assert_valid uri.to_s, data, :list => true
end
end
json-schema-2.6.0/test/test_load_ref_schema.rb 0000664 0000000 0000000 00000001760 12643714510 0021373 0 ustar 00root root 0000000 0000000 require File.expand_path('../test_helper', __FILE__)
class LoadRefSchemaTests < 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
end
json-schema-2.6.0/test/test_merge_missing_values.rb 0000664 0000000 0000000 00000003331 12643714510 0022503 0 ustar 00root root 0000000 0000000 require File.expand_path('../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.6.0/test/test_minitems.rb 0000664 0000000 0000000 00000000620 12643714510 0020117 0 ustar 00root root 0000000 0000000 require File.expand_path('../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] =~ /NilClass/)
end
end
json-schema-2.6.0/test/test_one_of.rb 0000664 0000000 0000000 00000005406 12643714510 0017546 0 ustar 00root root 0000000 0000000 require File.expand_path('../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 Fixnum 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 Hash did not match any of the required schemas. The schema specific errors were:
- oneOf #0:
- The property '#/a' of type Fixnum did not match the following type: string
- oneOf #1:
- The property '#/a' of type Fixnum 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.6.0/test/test_ruby_schema.rb 0000664 0000000 0000000 00000002147 12643714510 0020601 0 ustar 00root root 0000000 0000000 require File.expand_path('../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
end
json-schema-2.6.0/test/test_schema_loader.rb 0000664 0000000 0000000 00000004353 12643714510 0021067 0 ustar 00root root 0000000 0000000 require File.expand_path('../test_helper', __FILE__)
class TestSchemaReader < 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)
assert_raises(JSON::Schema::ReadRefused) do
reader.read('file://' + ADDRESS_SCHEMA_PATH)
end
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.6.0/test/test_schema_type_attribute.rb 0000664 0000000 0000000 00000001157 12643714510 0022664 0 ustar 00root root 0000000 0000000 require File.expand_path('../test_helper', __FILE__)
class TestSchemaTypeAttribute < 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.6.0/test/test_schema_validation.rb 0000664 0000000 0000000 00000011003 12643714510 0021741 0 ustar 00root root 0000000 0000000 require File.expand_path('../test_helper', __FILE__)
require 'tmpdir'
class JSONSchemaValidation < 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.6.0/test/test_stringify.rb 0000664 0000000 0000000 00000002377 12643714510 0020323 0 ustar 00root root 0000000 0000000 require File.expand_path('../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.6.0/test/test_uri_related.rb 0000664 0000000 0000000 00000003231 12643714510 0020572 0 ustar 00root root 0000000 0000000 # coding: utf-8
require File.expand_path('../test_helper', __FILE__)
class UriRelatedTest < 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.6.0/test/test_validator.rb 0000664 0000000 0000000 00000002656 12643714510 0020272 0 ustar 00root root 0000000 0000000 require File.expand_path('../test_helper', __FILE__)
class TestValidator < Minitest::Test
class MockReader
def read(location)
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://what.ever/schema' }
assert_valid schema, ['abc', 'def'], :schema_reader => reader, :list => true
refute_valid schema, ['abc', 'a'], :schema_reader => reader, :list => true
end
end