├── ruby-jsonschema.gemspec ├── Rakefile ├── README.rdoc ├── lib └── jsonschema.rb └── test └── jsonschema_test.rb /ruby-jsonschema.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | 3 | Gem::Specification.new do |s| 4 | s.name = %q{jsonschema} 5 | s.version = "1.0.0" 6 | 7 | s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= 8 | s.authors = ["Constellation"] 9 | s.date = %q{2009-09-13} 10 | s.description = %q{json schema library ruby porting from http://code.google.com/p/jsonschema/} 11 | s.email = %q{utatane.tea@gmail.com} 12 | s.extra_rdoc_files = ["README.rdoc"] 13 | s.files = ["README.rdoc", "Rakefile", "test/jsonschema_test.rb", "lib/jsonschema.rb"] 14 | s.homepage = %q{http://github.com/Constellation/jsonschema/tree/master} 15 | s.rdoc_options = ["--main", "README.rdoc", "--charset", "utf-8", "--line-numbers", "--inline-source"] 16 | s.require_paths = ["lib"] 17 | s.rubyforge_project = %q{jsonschema} 18 | s.rubygems_version = %q{1.3.5} 19 | s.summary = %q{json schema library ruby porting from http://code.google.com/p/jsonschema/} 20 | s.test_files = ["test/jsonschema_test.rb"] 21 | 22 | if s.respond_to? :specification_version then 23 | current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION 24 | s.specification_version = 3 25 | 26 | if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then 27 | else 28 | end 29 | else 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # vim: fileencoding=utf-8 2 | require 'rubygems' 3 | require 'rake' 4 | require 'rake/clean' 5 | require 'rake/testtask' 6 | require 'rubygems/package_task' 7 | require 'rake/task' 8 | require 'rake/contrib/rubyforgepublisher' 9 | require 'rake/contrib/sshpublisher' 10 | require 'fileutils' 11 | require './lib/jsonschema' 12 | include FileUtils 13 | 14 | $version = JSON::Schema::VERSION 15 | $readme = 'README.rdoc' 16 | $rdoc_opts = %W(--main #{$readme} --charset utf-8 --line-numbers --inline-source) 17 | $name = 'jsonschema' 18 | $github_name = 'ruby-jsonschema' 19 | $summary = 'json schema library ruby porting from http://code.google.com/p/jsonschema/' 20 | $author = 'Constellation' 21 | $email = 'utatane.tea@gmail.com' 22 | $page = 'http://github.com/Constellation/ruby-jsonchema/tree/master' 23 | #$exec = %W(jsonschema) 24 | $rubyforge_project = 'jsonschema' 25 | 26 | 27 | task :default => [:test] 28 | task :package => [:clean] 29 | 30 | Rake::TestTask.new("test") do |t| 31 | t.libs << "test" 32 | t.pattern = "test/**/*_test.rb" 33 | t.verbose = true 34 | end 35 | 36 | spec = Gem::Specification.new do |s| 37 | s.name = $name 38 | s.version = $version 39 | s.platform = Gem::Platform::RUBY 40 | s.has_rdoc = true 41 | s.extra_rdoc_files = [$readme] 42 | s.rdoc_options += $rdoc_opts 43 | s.summary = $summary 44 | s.description = $summary 45 | s.author = $author 46 | s.email = $email 47 | s.homepage = $page 48 | s.executables = $exec 49 | s.rubyforge_project = $rubyforge_project 50 | # s.bindir = 'bin' 51 | s.require_path = 'lib' 52 | s.test_files = Dir["test/*_test.rb"] 53 | # { 54 | # }.each do |dep, ver| 55 | # s.add_dependency(dep, ver) 56 | # end 57 | s.files = %w(README.rdoc Rakefile) + Dir["{bin,test,lib}/**/*"] 58 | end 59 | 60 | Gem::PackageTask.new(spec) do |p| 61 | p.need_tar = true 62 | p.gem_spec = spec 63 | end 64 | 65 | desc "gem spec" 66 | task :gemspec do 67 | File.open("#{$github_name}.gemspec", "wb") do |f| 68 | f << spec.to_ruby 69 | end 70 | end 71 | 72 | desc "gem build" 73 | task :build => [:gemspec] do 74 | sh "gem build #{$github_name}.gemspec" 75 | end 76 | 77 | desc "gem install" 78 | task :install => [:build] do 79 | sh "sudo gem install #{$name}-#{$version}.gem --local" 80 | end 81 | 82 | desc "gem uninstall" 83 | task :uninstall do 84 | sh "sudo gem uninstall #{$name}" 85 | end 86 | # vim: syntax=ruby 87 | -------------------------------------------------------------------------------- /README.rdoc: -------------------------------------------------------------------------------- 1 | = Ruby/jsonschema 2 | 3 | * http://github.com/Constellation/jsonchema 4 | 5 | == DESCRIPTION: 6 | 7 | json schema library ruby porting 8 | from http://code.google.com/p/jsonschema/ 9 | 10 | == SYNOPSIS: 11 | ruby code 12 | require 'jsonschema' 13 | schema = { 14 | "type" => "object", 15 | "properties" => { 16 | "prop01" => { 17 | "type" => "number", 18 | "maximum" => 10 19 | }, 20 | "prop02" => { 21 | "type" => "integer", 22 | "maximum" => 20 23 | } 24 | } 25 | } 26 | data = { 27 | "prop01"=> 5, 28 | "prop02"=> 10 29 | } 30 | JSON::Schema.validate(data, schema) 31 | 32 | if you have json library 33 | require 'json' 34 | require 'jsonschema' 35 | schema = File.open("path/to/schema.json", "rb"){|f| JSON.parse(f.read)} 36 | data = File.open("path/to/data.json", "rb"){|f| JSON.parse(f.read)} 37 | JSON::Schema.validate(data, schema) 38 | 39 | == INSTALL: 40 | 41 | gem source -a http://gemcutter.org 42 | sudo gem install jsonschema 43 | 44 | == CONTRIBUTORS: 45 | 46 | * Matt Coneybeare 47 | * hristian Bäuerlein 48 | 49 | == LICENSE: 50 | 51 | Ruby/jsonschema 52 | (The MIT License) 53 | 54 | Copyright (c) 2009 Constellation 55 | 56 | Permission is hereby granted, free of charge, to any person obtaining 57 | a copy of this software and associated documentation files (the 58 | 'Software'), to deal in the Software without restriction, including 59 | without limitation the rights to use, copy, modify, merge, publish, 60 | distribute, sublicense, and/or sell copies of the Software, and to 61 | permit persons to whom the Software is furnished to do so, subject to 62 | the following conditions: 63 | 64 | The above copyright notice and this permission notice shall be 65 | included in all copies or substantial portions of the Software. 66 | 67 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 68 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 69 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 70 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 71 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 72 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 73 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 74 | 75 | 76 | jsonschema 77 | http://code.google.com/p/jsonschema/ 78 | (The MIT License) 79 | 80 | Copyright (c) 2008 Ian Lewis, Yusuke Muraoka 81 | 82 | Permission is hereby granted, free of charge, to any person obtaining a copy of 83 | this software and associated documentation files (the "Software"), to deal in 84 | the Software without restriction, including without limitation the rights to 85 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 86 | of the Software, and to permit persons to whom the Software is furnished to do 87 | so, subject to the following conditions: 88 | 89 | The above copyright notice and this permission notice shall be included in all 90 | copies or substantial portions of the Software. 91 | 92 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 93 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 94 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 95 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 96 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 97 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 98 | SOFTWARE. 99 | 100 | -------------------------------------------------------------------------------- /lib/jsonschema.rb: -------------------------------------------------------------------------------- 1 | # vim: fileencoding=utf-8 2 | 3 | module JSON 4 | class Schema 5 | VERSION = '2.0.2' 6 | class ValueError < Exception;end 7 | class Undefined;end 8 | TypesMap = { 9 | "string" => String, 10 | "integer" => [Integer, Fixnum], 11 | "number" => [Integer, Float, Fixnum, Numeric], 12 | "boolean" => [TrueClass, FalseClass], 13 | "object" => Hash, 14 | "array" => Array, 15 | "null" => NilClass, 16 | "any" => nil 17 | } 18 | TypesList = [String, Integer, Float, Fixnum, Numeric, TrueClass, FalseClass, Hash, Array, NilClass] 19 | def initialize interactive 20 | @interactive = interactive 21 | @refmap = {} 22 | end 23 | 24 | def keys 25 | @keys ||= [] 26 | end 27 | 28 | def key_path 29 | keys.reject{|k| k == 'self'}.join(" > ") 30 | end 31 | 32 | def check_property value, schema, key, parent 33 | if schema 34 | keys.push key 35 | # if @interactive && schema['readonly'] 36 | # raise ValueError, "#{key_path} is a readonly field , it can not be changed" 37 | # end 38 | 39 | if schema['id'] 40 | @refmap[schema['id']] = schema 41 | end 42 | 43 | if schema['extends'] 44 | check_property(value, schema['extends'], key, parent) 45 | end 46 | 47 | if value == Undefined 48 | unless schema['optional'] 49 | raise ValueError, "#{key_path}: is missing and it is not optional" 50 | end 51 | 52 | # default 53 | if @interactive && !parent.include?(key) && !schema['default'].nil? 54 | unless schema["readonly"] 55 | parent[key] = schema['default'] 56 | end 57 | end 58 | else 59 | 60 | # type 61 | if schema['type'] 62 | check_type(value, schema['type'], key, parent) 63 | end 64 | 65 | # disallow 66 | if schema['disallow'] 67 | flag = true 68 | begin 69 | check_type(value, schema['disallow'], key, parent) 70 | rescue ValueError 71 | flag = false 72 | end 73 | raise ValueError, "#{key_path}: disallowed value was matched" if flag 74 | end 75 | 76 | unless value.nil? 77 | if value.kind_of? Array 78 | if schema['items'] 79 | if schema['items'].kind_of?(Array) 80 | schema['items'].each_with_index {|val, index| 81 | check_property(undefined_check(value, index), schema['items'][index], index, value) 82 | } 83 | if schema.include?('additionalProperties') 84 | additional = schema['additionalProperties'] 85 | if additional.kind_of?(FalseClass) 86 | if schema['items'].size < value.size 87 | raise ValueError, "#{key_path}: There are more values in the array than are allowed by the items and additionalProperties restrictions." 88 | end 89 | else 90 | value.each_with_index {|val, index| 91 | check_property(undefined_check(value, index), schema['additionalProperties'], index, value) 92 | } 93 | end 94 | end 95 | else 96 | value.each_with_index {|val, index| 97 | check_property(undefined_check(value, index), schema['items'], index, value) 98 | } 99 | end 100 | end 101 | if schema['minItems'] && value.size < schema['minItems'] 102 | raise ValueError, "#{key_path}: There must be a minimum of #{schema['minItems']} in the array" 103 | end 104 | if schema['maxItems'] && value.size > schema['maxItems'] 105 | raise ValueError, "#{key_path}: There must be a maximum of #{schema['maxItems']} in the array" 106 | end 107 | elsif schema['properties'] 108 | check_object(value, schema['properties'], schema['additionalProperties']) 109 | elsif schema.include?('additionalProperties') 110 | additional = schema['additionalProperties'] 111 | unless additional.kind_of?(TrueClass) 112 | if additional.kind_of?(Hash) || additional.kind_of?(FalseClass) 113 | properties = {} 114 | value.each {|k, val| 115 | if additional.kind_of?(FalseClass) 116 | raise ValueError, "#{key_path}: Additional properties not defined by 'properties' are not allowed in field '#{k}'" 117 | else 118 | check_property(val, schema['additionalProperties'], k, value) 119 | end 120 | } 121 | else 122 | raise ValueError, "#{key_path}: additionalProperties schema definition for field '#{}' is not an object" 123 | end 124 | end 125 | end 126 | 127 | if value.kind_of?(String) 128 | # pattern 129 | if schema['pattern'] && !(value =~ Regexp.new(schema['pattern'])) 130 | raise ValueError, "#{key_path}: does not match the regex pattern #{schema['pattern']}" 131 | end 132 | 133 | strlen = value.split(//).size 134 | # maxLength 135 | if schema['maxLength'] && strlen > schema['maxLength'] 136 | raise ValueError, "#{key_path}: may only be #{schema['maxLength']} characters long" 137 | end 138 | 139 | # minLength 140 | if schema['minLength'] && strlen < schema['minLength'] 141 | raise ValueError, "#{key_path}: must be at least #{schema['minLength']} characters long" 142 | end 143 | end 144 | 145 | if value.kind_of?(Numeric) 146 | 147 | # minimum + minimumCanEqual 148 | if schema['minimum'] 149 | minimumCanEqual = schema.fetch('minimumCanEqual', Undefined) 150 | if minimumCanEqual == Undefined || minimumCanEqual 151 | if value < schema['minimum'] 152 | raise ValueError, "#{key_path}: must have a minimum value of #{schema['minimum']}" 153 | end 154 | else 155 | if value <= schema['minimum'] 156 | raise ValueError, "#{key_path}: must have a minimum value of #{schema['minimum']}" 157 | end 158 | end 159 | end 160 | 161 | # maximum + maximumCanEqual 162 | if schema['maximum'] 163 | maximumCanEqual = schema.fetch('maximumCanEqual', Undefined) 164 | if maximumCanEqual == Undefined || maximumCanEqual 165 | if value > schema['maximum'] 166 | raise ValueError, "#{key_path}: must have a maximum value of #{schema['maximum']}" 167 | end 168 | else 169 | if value >= schema['maximum'] 170 | raise ValueError, "#{key_path}: must have a maximum value of #{schema['maximum']}" 171 | end 172 | end 173 | end 174 | 175 | # maxDecimal 176 | if schema['maxDecimal'] && schema['maxDecimal'].kind_of?(Numeric) 177 | if value.to_s =~ /\.\d{#{schema['maxDecimal']+1},}/ 178 | raise ValueError, "#{key_path}: may only have #{schema['maxDecimal']} digits of decimal places" 179 | end 180 | end 181 | 182 | end 183 | 184 | # enum 185 | if schema['enum'] 186 | unless(schema['enum'].detect{|enum| enum == value }) 187 | raise ValueError, "#{key_path}: does not have a value in the enumeration #{schema['enum'].join(", ")}" 188 | end 189 | end 190 | 191 | # description 192 | if schema['description'] && !schema['description'].kind_of?(String) 193 | raise ValueError, "#{key_path}: The description for field '#{value}' must be a string" 194 | end 195 | 196 | # title 197 | if schema['title'] && !schema['title'].kind_of?(String) 198 | raise ValueError, "#{key_path}: The title for field '#{value}' must be a string" 199 | end 200 | 201 | # format 202 | if schema['format'] 203 | end 204 | 205 | end 206 | end 207 | keys.pop 208 | end 209 | end 210 | 211 | def check_object value, object_type_def, additional 212 | if object_type_def.kind_of? Hash 213 | if !value.kind_of?(Hash) || value.kind_of?(Array) 214 | raise ValueError, "an object is required" 215 | end 216 | 217 | object_type_def.each {|key, odef| 218 | if key.index('__') != 0 219 | check_property(undefined_check(value, key), odef, key, value) 220 | end 221 | } 222 | end 223 | value.each {|key, val| 224 | if key.index('__') != 0 && object_type_def && !object_type_def[key] && additional == false 225 | raise ValueError, "The property #{key_path} > #{key} is not defined in the schema and the schema does not allow additional properties" 226 | end 227 | requires = object_type_def && object_type_def[key] && object_type_def[key]['requires'] 228 | if requires && !value.include?(requires) 229 | raise ValueError, "The presence of the property #{key_path} > #{key} requires that #{requires} also be present" 230 | end 231 | if object_type_def && object_type_def.kind_of?(Hash) && !object_type_def.include?(key) 232 | check_property(val, additional, key, value) 233 | end 234 | if !@interactive && val && val['$schema'] 235 | check_property(val, val['$schema'], key, value) 236 | end 237 | } 238 | end 239 | 240 | def check_type value, type, key, parent 241 | converted_fieldtype = convert_type(type) 242 | if converted_fieldtype 243 | if converted_fieldtype.kind_of? Array 244 | datavalid = false 245 | converted_fieldtype.each do |t| 246 | begin 247 | check_type(value, t, key, parent) 248 | datavalid = true 249 | break 250 | rescue ValueError 251 | next 252 | end 253 | end 254 | unless datavalid 255 | raise ValueError, "#{key_path}: #{value.class} value found, but a #{type} is required" 256 | end 257 | elsif converted_fieldtype.kind_of? Hash 258 | check_property(value, type, key, parent) 259 | else 260 | unless value.kind_of? converted_fieldtype 261 | raise ValueError, "#{key_path}: #{value.class} value found, but a #{type} is required" 262 | end 263 | end 264 | end 265 | end 266 | 267 | def undefined_check value, key 268 | value.fetch(key, Undefined) 269 | end 270 | 271 | def convert_type fieldtype 272 | if TypesList.include?(fieldtype) || fieldtype.kind_of?(Hash) 273 | return fieldtype 274 | elsif fieldtype.kind_of? Array 275 | converted_fields = [] 276 | fieldtype.each do |subfieldtype| 277 | converted_fields << convert_type(subfieldtype) 278 | end 279 | return converted_fields 280 | elsif !fieldtype 281 | return nil 282 | else 283 | fieldtype = fieldtype.to_s 284 | if TypesMap.include?(fieldtype) 285 | return TypesMap[fieldtype] 286 | else 287 | raise ValueError, "Field type '#{fieldtype}' is not supported." 288 | end 289 | end 290 | end 291 | 292 | def validate instance, schema 293 | @tree = { 294 | 'self' => instance 295 | } 296 | if schema 297 | check_property(instance, schema, 'self', @tree) 298 | elsif instance && instance['$schema'] 299 | # self definition schema 300 | check_property(instance, instance['$schema'], 'self', @tree) 301 | end 302 | return @tree['self'] 303 | end 304 | 305 | class << self 306 | def validate data, schema=nil, interactive=true 307 | validator = JSON::Schema.new(interactive) 308 | validator.validate(data, schema) 309 | end 310 | end 311 | end 312 | end 313 | 314 | -------------------------------------------------------------------------------- /test/jsonschema_test.rb: -------------------------------------------------------------------------------- 1 | require 'test/unit' 2 | require 'open-uri' 3 | require 'pp' 4 | require File.dirname(__FILE__) + '/../lib/jsonschema' 5 | 6 | class JSONSchemaTest < Test::Unit::TestCase 7 | def test_self_schema 8 | data1 = { 9 | "$schema"=> { 10 | "properties"=> { 11 | "name"=> { 12 | "type"=> "string" 13 | }, 14 | "age" => { 15 | "type"=> "integer", 16 | "maximum"=> 125, 17 | "optional"=> true 18 | } 19 | } 20 | }, 21 | "name" => "John Doe", 22 | "age" => 30, 23 | "type" => "object" 24 | } 25 | assert_nothing_raised{ 26 | JSON::Schema.validate(data1) 27 | } 28 | data2 = { 29 | "$schema"=> { 30 | "properties"=> { 31 | "name"=> { 32 | "type"=> "integer" 33 | }, 34 | "age" => { 35 | "type"=> "integer", 36 | "maximum"=> 125, 37 | "optional"=> true 38 | } 39 | } 40 | }, 41 | "name" => "John Doe", 42 | "age" => 30, 43 | "type" => "object" 44 | } 45 | assert_raise(JSON::Schema::ValueError){ 46 | JSON::Schema.validate(data2) 47 | } 48 | data3 = { 49 | "$schema"=> { 50 | "properties"=> { 51 | "name"=> { 52 | "type"=> "integer" 53 | }, 54 | "age" => { 55 | "type"=> "integer", 56 | "maximum"=> 125, 57 | "optional"=> true 58 | } 59 | } 60 | }, 61 | "name" => "John Doe", 62 | } 63 | assert_raise(JSON::Schema::ValueError){ 64 | JSON::Schema.validate(data3) 65 | } 66 | end 67 | 68 | def test_maximum 69 | schema1 = { 70 | "type" => "object", 71 | "properties" => { 72 | "prop01" => { 73 | "type" => "number", 74 | "maximum" => 10 75 | }, 76 | "prop02" => { 77 | "type" => "integer", 78 | "maximum" => 20 79 | } 80 | } 81 | } 82 | data1 = { 83 | "prop01"=> 5, 84 | "prop02"=> 10 85 | } 86 | data2 = { 87 | "prop01"=> 10, 88 | "prop02"=> 20 89 | } 90 | data3 = { 91 | "prop01"=> 11, 92 | "prop02"=> 19 93 | } 94 | data4 = { 95 | "prop01"=> 9, 96 | "prop02"=> 21 97 | } 98 | assert_nothing_raised{ 99 | JSON::Schema.validate(data1, schema1) 100 | } 101 | assert_nothing_raised{ 102 | JSON::Schema.validate(data2, schema1) 103 | } 104 | assert_raise(JSON::Schema::ValueError){ 105 | JSON::Schema.validate(data3, schema1) 106 | } 107 | assert_raise(JSON::Schema::ValueError){ 108 | JSON::Schema.validate(data4, schema1) 109 | } 110 | schema2 = { 111 | "type" => "object", 112 | "properties" => { 113 | "prop01" => { 114 | "type" => "number", 115 | "maximum" => 10, 116 | "maximumCanEqual" => true 117 | }, 118 | "prop02" => { 119 | "type" => "integer", 120 | "maximum" => 20, 121 | "maximumCanEqual" => false 122 | } 123 | } 124 | } 125 | data5 = { 126 | "prop01"=> 10, 127 | "prop02"=> 10 128 | } 129 | data6 = { 130 | "prop01"=> 10, 131 | "prop02"=> 19 132 | } 133 | data7 = { 134 | "prop01"=> 11, 135 | "prop02"=> 19 136 | } 137 | data8 = { 138 | "prop01"=> 9, 139 | "prop02"=> 20 140 | } 141 | assert_nothing_raised{ 142 | JSON::Schema.validate(data5, schema2) 143 | } 144 | assert_nothing_raised{ 145 | JSON::Schema.validate(data6, schema2) 146 | } 147 | assert_raise(JSON::Schema::ValueError){ 148 | JSON::Schema.validate(data7, schema2) 149 | } 150 | assert_raise(JSON::Schema::ValueError){ 151 | JSON::Schema.validate(data8, schema2) 152 | } 153 | end 154 | 155 | def test_extends 156 | schema = { 157 | "type" => "object", 158 | "properties" => { 159 | "prop01" => { 160 | "type" => "number", 161 | "minimum" => 10 162 | }, 163 | "prop02" => {} 164 | } 165 | } 166 | schema["properties"]["prop02"]["extends"] = schema["properties"]["prop01"] 167 | data1 = { 168 | "prop01"=> 21, 169 | "prop02"=> 21 170 | } 171 | data2 = { 172 | "prop01"=> 10, 173 | "prop02"=> 20 174 | } 175 | data3 = { 176 | "prop01"=> 9, 177 | "prop02"=> 21 178 | } 179 | data4 = { 180 | "prop01"=> 10, 181 | "prop02"=> 9 182 | } 183 | assert_nothing_raised{ 184 | JSON::Schema.validate(data1, schema) 185 | } 186 | assert_nothing_raised{ 187 | JSON::Schema.validate(data2, schema) 188 | } 189 | assert_raise(JSON::Schema::ValueError){ 190 | JSON::Schema.validate(data3, schema) 191 | } 192 | assert_raise(JSON::Schema::ValueError){ 193 | JSON::Schema.validate(data4, schema) 194 | } 195 | end 196 | 197 | def test_minimum 198 | schema1 = { 199 | "type" => "object", 200 | "properties" => { 201 | "prop01" => { 202 | "type" => "number", 203 | "minimum" => 10 204 | }, 205 | "prop02" => { 206 | "type" => "integer", 207 | "minimum" => 20 208 | } 209 | } 210 | } 211 | data1 = { 212 | "prop01"=> 21, 213 | "prop02"=> 21 214 | } 215 | data2 = { 216 | "prop01"=> 10, 217 | "prop02"=> 20 218 | } 219 | data3 = { 220 | "prop01"=> 9, 221 | "prop02"=> 21 222 | } 223 | data4 = { 224 | "prop01"=> 10, 225 | "prop02"=> 19 226 | } 227 | assert_nothing_raised{ 228 | JSON::Schema.validate(data1, schema1) 229 | } 230 | assert_nothing_raised{ 231 | JSON::Schema.validate(data2, schema1) 232 | } 233 | assert_raise(JSON::Schema::ValueError){ 234 | JSON::Schema.validate(data3, schema1) 235 | } 236 | assert_raise(JSON::Schema::ValueError){ 237 | JSON::Schema.validate(data4, schema1) 238 | } 239 | schema2 = { 240 | "type" => "object", 241 | "properties" => { 242 | "prop01" => { 243 | "type" => "number", 244 | "minimum" => 10, 245 | "minimumCanEqual" => false 246 | }, 247 | "prop02" => { 248 | "type" => "integer", 249 | "minimum" => 19, 250 | "minimumCanEqual" => true 251 | } 252 | } 253 | } 254 | data5 = { 255 | "prop01"=> 11, 256 | "prop02"=> 19 257 | } 258 | data6 = { 259 | "prop01"=> 10, 260 | "prop02"=> 19 261 | } 262 | data7 = { 263 | "prop01"=> 11, 264 | "prop02"=> 18 265 | } 266 | assert_nothing_raised{ 267 | JSON::Schema.validate(data5, schema2) 268 | } 269 | assert_raise(JSON::Schema::ValueError){ 270 | JSON::Schema.validate(data6, schema2) 271 | } 272 | assert_raise(JSON::Schema::ValueError){ 273 | JSON::Schema.validate(data7, schema2) 274 | } 275 | end 276 | 277 | def test_minItems 278 | schema1 = { 279 | "type" => "array", 280 | "minItems" => 4 281 | } 282 | schema2 = { 283 | "minItems" => 4 284 | } 285 | data1 = [1, 2, "3", 4.0] 286 | data2 = [1, 2, "3", 4.0, 5.00] 287 | data3 = "test" 288 | data4 = [1, 2, "3"] 289 | assert_nothing_raised{ 290 | JSON::Schema.validate(data1, schema1) 291 | } 292 | assert_nothing_raised{ 293 | JSON::Schema.validate(data2, schema1) 294 | } 295 | assert_nothing_raised{ 296 | JSON::Schema.validate(data3, schema2) 297 | } 298 | assert_nothing_raised{ 299 | JSON::Schema.validate(data2, schema2) 300 | } 301 | assert_raise(JSON::Schema::ValueError){ 302 | JSON::Schema.validate(data4, schema1) 303 | } 304 | assert_raise(JSON::Schema::ValueError){ 305 | JSON::Schema.validate(data4, schema2) 306 | } 307 | end 308 | 309 | def test_maxItems 310 | schema1 = { 311 | "type" => "array", 312 | "maxItems" => 4 313 | } 314 | schema2 = { 315 | "maxItems" => 4 316 | } 317 | data1 = [1, 2, "3", 4.0] 318 | data2 = [1, 2, "3"] 319 | data3 = "test" 320 | data4 = [1, 2, "3", 4.0, 5.00] 321 | assert_nothing_raised{ 322 | JSON::Schema.validate(data1, schema1) 323 | } 324 | assert_nothing_raised{ 325 | JSON::Schema.validate(data2, schema1) 326 | } 327 | assert_nothing_raised{ 328 | JSON::Schema.validate(data3, schema2) 329 | } 330 | assert_nothing_raised{ 331 | JSON::Schema.validate(data2, schema2) 332 | } 333 | assert_raise(JSON::Schema::ValueError){ 334 | JSON::Schema.validate(data4, schema1) 335 | } 336 | assert_raise(JSON::Schema::ValueError){ 337 | JSON::Schema.validate(data4, schema2) 338 | } 339 | end 340 | 341 | def test_minLength 342 | schema = { 343 | "minLength" => 4 344 | } 345 | data1 = "test" 346 | data2 = "string" 347 | data3 = 123 348 | data4 = [1, 2, "3"] 349 | data5 = "car" 350 | assert_nothing_raised{ 351 | JSON::Schema.validate(data1, schema) 352 | } 353 | assert_nothing_raised{ 354 | JSON::Schema.validate(data2, schema) 355 | } 356 | assert_nothing_raised{ 357 | JSON::Schema.validate(data3, schema) 358 | } 359 | assert_nothing_raised{ 360 | JSON::Schema.validate(data4, schema) 361 | } 362 | assert_raise(JSON::Schema::ValueError){ 363 | JSON::Schema.validate(data5, schema) 364 | } 365 | end 366 | def test_maxLength 367 | schema = { 368 | "maxLength" => 4 369 | } 370 | data1 = "test" 371 | data2 = "car" 372 | data3 = 12345 373 | data4 = [1, 2, "3", 4, 5] 374 | data5 = "string" 375 | assert_nothing_raised{ 376 | JSON::Schema.validate(data1, schema) 377 | } 378 | assert_nothing_raised{ 379 | JSON::Schema.validate(data2, schema) 380 | } 381 | assert_nothing_raised{ 382 | JSON::Schema.validate(data3, schema) 383 | } 384 | assert_nothing_raised{ 385 | JSON::Schema.validate(data4, schema) 386 | } 387 | assert_raise(JSON::Schema::ValueError){ 388 | JSON::Schema.validate(data5, schema) 389 | } 390 | end 391 | 392 | def test_maxDecimal 393 | schema = { 394 | "type" => "number", 395 | "maxDecimal" => 3 396 | } 397 | data1 = 10.20 398 | data2 = 10.204 399 | data3 = 10 400 | data4 = 10.04092 401 | assert_nothing_raised{ 402 | JSON::Schema.validate(data1, schema) 403 | } 404 | assert_nothing_raised{ 405 | JSON::Schema.validate(data2, schema) 406 | } 407 | assert_nothing_raised{ 408 | JSON::Schema.validate(data3, schema) 409 | } 410 | assert_raise(JSON::Schema::ValueError){ 411 | JSON::Schema.validate(data4, schema) 412 | } 413 | end 414 | 415 | def test_properties 416 | schema = { 417 | "type"=>"object", 418 | "properties"=>{ 419 | "prop01"=>{ 420 | "type"=>"string", 421 | }, 422 | "prop02"=>{ 423 | "type"=>"number", 424 | "optional"=>true 425 | }, 426 | "prop03"=>{ 427 | "type"=>"integer", 428 | }, 429 | "prop04"=>{ 430 | "type"=>"boolean", 431 | }, 432 | "prop05"=>{ 433 | "type"=>"object", 434 | "optional"=>true, 435 | "properties"=>{ 436 | "subprop01"=>{ 437 | "type"=>"string", 438 | }, 439 | "subprop02"=>{ 440 | "type"=>"string", 441 | "optional"=>false 442 | } 443 | } 444 | } 445 | } 446 | } 447 | data1 = { 448 | "prop01"=>"test", 449 | "prop02"=>1.20, 450 | "prop03"=>1, 451 | "prop04"=>true, 452 | "prop05"=>{ 453 | "subprop01"=>"test", 454 | "subprop02"=>"test2" 455 | } 456 | } 457 | assert_nothing_raised{ 458 | JSON::Schema.validate(data1, schema) 459 | } 460 | data2 = { 461 | "prop01"=>"test", 462 | "prop02"=>1.20, 463 | "prop03"=>1, 464 | "prop04"=>true 465 | } 466 | assert_nothing_raised{ 467 | JSON::Schema.validate(data2, schema) 468 | } 469 | data3 = { 470 | "prop02"=>1.60, 471 | "prop05"=>{ 472 | "subprop01"=>"test" 473 | } 474 | } 475 | assert_raise(JSON::Schema::ValueError){ 476 | JSON::Schema.validate(data3, schema) 477 | } 478 | end 479 | 480 | def test_title 481 | schema1 = { 482 | "title"=>"My Title for My Schema" 483 | } 484 | schema2 = { 485 | "title"=>1233 486 | } 487 | data = "whatever" 488 | assert_nothing_raised{ 489 | JSON::Schema.validate(data, schema1) 490 | } 491 | assert_raise(JSON::Schema::ValueError){ 492 | JSON::Schema.validate(data, schema2) 493 | } 494 | end 495 | 496 | def test_requires 497 | schema = { 498 | "type"=>"object", 499 | "properties"=>{ 500 | "prop01"=>{ 501 | "type"=>"string", 502 | "optional"=>true 503 | }, 504 | "prop02"=>{ 505 | "type"=>"number", 506 | "optional"=>true, 507 | "requires"=>"prop01" 508 | } 509 | } 510 | } 511 | data1 = {} 512 | data2 = { 513 | "prop01"=>"test", 514 | "prop02"=>2 515 | } 516 | assert_nothing_raised{ 517 | JSON::Schema.validate(data1, schema) 518 | } 519 | assert_nothing_raised{ 520 | JSON::Schema.validate(data2, schema) 521 | } 522 | data3 = { 523 | "prop02"=>2 524 | } 525 | assert_raise(JSON::Schema::ValueError){ 526 | JSON::Schema.validate(data3, schema) 527 | } 528 | end 529 | 530 | def test_pattern 531 | schema = { 532 | "pattern"=>"^[A-Za-z0-9][A-Za-z0-9\.]*@([A-Za-z0-9]+\.)+[A-Za-z0-9]+$" 533 | } 534 | data1 = "my.email01@gmail.com" 535 | assert_nothing_raised{ 536 | JSON::Schema.validate(data1, schema) 537 | } 538 | data2 = 123 539 | assert_nothing_raised{ 540 | JSON::Schema.validate(data2, schema) 541 | } 542 | data3 = "whatever" 543 | assert_raise(JSON::Schema::ValueError){ 544 | JSON::Schema.validate(data3, schema) 545 | } 546 | end 547 | 548 | def test_optional 549 | schema = { 550 | "type"=>"object", 551 | "properties"=>{ 552 | "prop01"=>{ 553 | "type"=>"string" 554 | }, 555 | "prop02"=>{ 556 | "type"=>"number", 557 | "optional"=>true 558 | }, 559 | "prop03"=>{ 560 | "type"=>"integer" 561 | }, 562 | "prop04"=>{ 563 | "type"=>"boolean", 564 | "optional"=>false 565 | } 566 | } 567 | } 568 | data1 = { 569 | "prop01"=>"test", 570 | "prop03"=>1, 571 | "prop04"=>false 572 | } 573 | assert_nothing_raised{ 574 | JSON::Schema.validate(data1, schema) 575 | } 576 | data2 = { 577 | "prop02"=>"blah" 578 | } 579 | data3 = { 580 | "prop01"=>"blah" 581 | } 582 | data4 = { 583 | "prop01"=>"test", 584 | "prop03"=>1, 585 | } 586 | assert_raise(JSON::Schema::ValueError){ 587 | JSON::Schema.validate(data2, schema) 588 | } 589 | assert_raise(JSON::Schema::ValueError){ 590 | JSON::Schema.validate(data3, schema) 591 | } 592 | assert_raise(JSON::Schema::ValueError){ 593 | JSON::Schema.validate(data4, schema) 594 | } 595 | end 596 | 597 | def test_default 598 | schema1 = { 599 | "properties"=>{ 600 | "test"=>{ 601 | "optional"=>true, 602 | "default"=>10 603 | }, 604 | } 605 | } 606 | schema2 = { 607 | "properties"=>{ 608 | "test"=>{ 609 | "optional"=>true, 610 | "default"=>10, 611 | "readonly"=>true 612 | } 613 | } 614 | } 615 | data1 = {} 616 | assert_nothing_raised{ 617 | JSON::Schema.validate(data1, schema1) 618 | } 619 | assert_equal(10, data1["test"]) 620 | 621 | data2 = {} 622 | assert_nothing_raised{ 623 | JSON::Schema.validate(data2, schema2) 624 | } 625 | assert_not_equal(10, data2["test"]) 626 | 627 | data3 = {} 628 | assert_nothing_raised{ 629 | JSON::Schema.validate(data3, schema1, true) 630 | } 631 | assert_equal(10, data3["test"]) 632 | 633 | data4 = {} 634 | assert_nothing_raised{ 635 | JSON::Schema.validate(data4, schema1, false) 636 | } 637 | assert_not_equal(10, data4["test"]) 638 | end 639 | 640 | def test_description 641 | schema1 = { 642 | "description"=>"My Description for My Schema" 643 | } 644 | schema2 = { 645 | "description"=>1233 646 | } 647 | data = "whatever" 648 | assert_nothing_raised{ 649 | JSON::Schema.validate(data, schema1) 650 | } 651 | assert_raise(JSON::Schema::ValueError){ 652 | JSON::Schema.validate(data, schema2) 653 | } 654 | end 655 | 656 | def test_type 657 | # schema 658 | schema1 = { 659 | "type"=>[ 660 | { 661 | "type"=>"array", 662 | "minItems"=>10 663 | }, 664 | { 665 | "type"=>"string", 666 | "pattern"=>"^0+$" 667 | } 668 | ] 669 | } 670 | data1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 671 | data2 = "0" 672 | data3 = 1203 673 | assert_nothing_raised{ 674 | JSON::Schema.validate(data1, schema1) 675 | } 676 | assert_nothing_raised{ 677 | JSON::Schema.validate(data2, schema1) 678 | } 679 | assert_raise(JSON::Schema::ValueError){ 680 | JSON::Schema.validate(data3, schema1) 681 | } 682 | 683 | # integer phase 684 | [1, 89, 48, 32, 49, 42].each do |item| 685 | assert_nothing_raised{ 686 | JSON::Schema.validate(item, {"type"=>"integer"}) 687 | } 688 | end 689 | [1.2, "bad", {"test" => "blah"}, [32, 49], nil, true].each do |item| 690 | assert_raise(JSON::Schema::ValueError){ 691 | JSON::Schema.validate(item, {"type"=>"integer"}) 692 | } 693 | end 694 | 695 | # string phase 696 | ["surrender?", "nuts!", "ok", "@hsuha", "\'ok?\'", "blah"].each do |item| 697 | assert_nothing_raised{ 698 | JSON::Schema.validate(item, {"type"=>"string"}) 699 | } 700 | end 701 | [1.2, 1, {"test" => "blah"}, [32, 49], nil, true].each do |item| 702 | assert_raise(JSON::Schema::ValueError){ 703 | JSON::Schema.validate(item, {"type"=>"string"}) 704 | } 705 | end 706 | 707 | # number phase 708 | [1.2, 89.42, 48.5224242, 32, 49, 42.24324].each do |item| 709 | assert_nothing_raised{ 710 | JSON::Schema.validate(item, {"type"=>"number"}) 711 | } 712 | end 713 | ["bad", {"test"=>"blah"}, [32.42, 494242], nil, true].each do |item| 714 | assert_raise(JSON::Schema::ValueError){ 715 | JSON::Schema.validate(item, {"type"=>"number"}) 716 | } 717 | end 718 | 719 | # boolean phase 720 | [true, false].each do |item| 721 | assert_nothing_raised{ 722 | JSON::Schema.validate(item, {"type"=>"boolean"}) 723 | } 724 | end 725 | [1.2, "False", {"test" => "blah"}, [32, 49], nil, 1, 0].each do |item| 726 | assert_raise(JSON::Schema::ValueError){ 727 | JSON::Schema.validate(item, {"type"=>"boolean"}) 728 | } 729 | end 730 | 731 | # object phase 732 | [{"blah"=>"test"}, {"this"=>{"blah"=>"test"}}, {1=>2, 10=>20}].each do |item| 733 | assert_nothing_raised{ 734 | JSON::Schema.validate(item, {"type"=>"object"}) 735 | } 736 | end 737 | [1.2, "bad", 123, [32, 49], nil, true].each do |item| 738 | assert_raise(JSON::Schema::ValueError){ 739 | JSON::Schema.validate(item, {"type"=>"object"}) 740 | } 741 | end 742 | 743 | # array phase 744 | [[1, 89], [48, {"test"=>"blah"}, "49", 42]].each do |item| 745 | assert_nothing_raised{ 746 | JSON::Schema.validate(item, {"type"=>"array"}) 747 | } 748 | end 749 | [1.2, "bad", {"test"=>"blah"}, 1234, nil, true].each do |item| 750 | assert_raise(JSON::Schema::ValueError){ 751 | JSON::Schema.validate(item, {"type"=>"array"}) 752 | } 753 | end 754 | 755 | # null phase 756 | assert_nothing_raised{ 757 | JSON::Schema.validate(nil, {"type"=>"null"}) 758 | } 759 | [1.2, "bad", {"test"=>"blah"}, [32, 49], 1284, true].each do |item| 760 | assert_raise(JSON::Schema::ValueError){ 761 | JSON::Schema.validate(item, {"type"=>"null"}) 762 | } 763 | end 764 | 765 | # any phase 766 | [1.2, "bad", {"test"=>"blah"}, [32, 49], nil, 1284, true].each do |item| 767 | assert_nothing_raised{ 768 | JSON::Schema.validate(item, {"type"=>"any"}) 769 | } 770 | end 771 | 772 | end 773 | 774 | def test_items 775 | schema1 = { 776 | "type"=>"array", 777 | "items"=>{ 778 | "type"=>"string" 779 | } 780 | } 781 | schema2 = { 782 | "type"=>"array", 783 | "items"=>[ 784 | {"type"=>"integer"}, 785 | {"type"=>"string"}, 786 | {"type"=>"boolean"} 787 | ] 788 | } 789 | data1 = ["string", "another string", "mystring"] 790 | data2 = ["JSON Schema is cool", "yet another string"] 791 | assert_nothing_raised{ 792 | JSON::Schema.validate(data1, schema1) 793 | } 794 | assert_nothing_raised{ 795 | JSON::Schema.validate(data2, schema1) 796 | } 797 | data3 = ["string", "another string", 1] 798 | assert_raise(JSON::Schema::ValueError){ 799 | JSON::Schema.validate(data3, schema1) 800 | } 801 | data4 = [1, "More strings?", true] 802 | data5 = [12482, "Yes, more strings", false] 803 | assert_nothing_raised{ 804 | JSON::Schema.validate(data4, schema2) 805 | } 806 | assert_nothing_raised{ 807 | JSON::Schema.validate(data5, schema2) 808 | } 809 | data6 = [1294, "Ok. I give up"] 810 | assert_raise(JSON::Schema::ValueError){ 811 | JSON::Schema.validate(data6, schema2) 812 | } 813 | data7 = [1294, "Ok. I give up", "Not a boolean"] 814 | assert_raise(JSON::Schema::ValueError){ 815 | JSON::Schema.validate(data7, schema2) 816 | } 817 | end 818 | 819 | def test_enum 820 | schema = { 821 | "enum"=>["test", true, 123, ["???"]] 822 | } 823 | ["test", true, 123, ["???"]].each do |item| 824 | assert_nothing_raised{ 825 | JSON::Schema.validate(item, schema) 826 | } 827 | end 828 | assert_raise(JSON::Schema::ValueError){ 829 | JSON::Schema.validate("unknown", schema) 830 | } 831 | end 832 | 833 | 834 | def test_additionalProperties 835 | schema1 = { 836 | "additionalProperties"=>{ 837 | "type" => "integer" 838 | } 839 | } 840 | [1, 89, 48, 32, 49, 42].each do |item| 841 | assert_nothing_raised{ 842 | JSON::Schema.validate({"prop" => item}, schema1) 843 | } 844 | end 845 | [1.2, "bad", {"test"=>"blah"}, [32, 49], nil, true].each do |item| 846 | assert_raise(JSON::Schema::ValueError){ 847 | JSON::Schema.validate({"prop" => item}, schema1) 848 | } 849 | end 850 | schema2 = { 851 | "properties" => { 852 | "prop1" => {"type" => "integer"}, 853 | "prop2" => {"type" => "string" } 854 | }, 855 | "additionalProperties" => { 856 | "type" => ["string", "number"] 857 | } 858 | } 859 | [1, "test", 48, "ok", 4.9, 42].each do |item| 860 | assert_nothing_raised{ 861 | JSON::Schema.validate({ 862 | "prop1" => 123, 863 | "prop2" => "this is prop2", 864 | "prop3" => item 865 | }, schema2) 866 | } 867 | end 868 | [{"test"=>"blah"}, [32, 49], nil, true].each do |item| 869 | assert_raise(JSON::Schema::ValueError){ 870 | JSON::Schema.validate({ 871 | "prop1" => 123, 872 | "prop2" => "this is prop2", 873 | "prop3" => item 874 | }, schema2) 875 | } 876 | end 877 | schema3 = { 878 | "additionalProperties" => true 879 | } 880 | [1.2, 1, {"test"=>"blah"}, [32, 49], nil, true, "blah"].each do |item| 881 | assert_nothing_raised{ 882 | JSON::Schema.validate({"prop" => item}, schema3) 883 | } 884 | end 885 | schema4 = { 886 | "additionalProperties" => false 887 | } 888 | ["bad", {"test"=>"blah"}, [32.42, 494242], nil, true, 1.34].each do |item| 889 | assert_raise(JSON::Schema::ValueError){ 890 | JSON::Schema.validate({"prop" => item}, schema4) 891 | } 892 | end 893 | end 894 | 895 | def test_disallow 896 | # multi phase 897 | schema = {"disallow"=>["null","integer","string"]} 898 | [nil, 183, "mystring"].each do |item| 899 | assert_raise(JSON::Schema::ValueError){ 900 | JSON::Schema.validate(item, schema) 901 | } 902 | end 903 | [1.2, {"test"=>"blah"}, [32, 49], true].each do |item| 904 | assert_nothing_raised{ 905 | JSON::Schema.validate(item, schema) 906 | } 907 | end 908 | 909 | # any phase 910 | [1.2, "bad", {"test"=>"blah"}, [32, 49], nil, 1284, true].each do |item| 911 | assert_raise(JSON::Schema::ValueError){ 912 | JSON::Schema.validate(item, {"disallow"=>"any"}) 913 | } 914 | end 915 | 916 | # null phase 917 | assert_raise(JSON::Schema::ValueError){ 918 | JSON::Schema.validate(nil, {"disallow"=>"null"}) 919 | } 920 | [1.2, "bad", {"test"=>"blah"}, [32, 49], 1284, true].each do |item| 921 | assert_nothing_raised{ 922 | JSON::Schema.validate(item, {"disallow"=>"null"}) 923 | } 924 | end 925 | 926 | # array phase 927 | [[1, 89], [48, {"test"=>"blah"}, "49", 42]].each do |item| 928 | assert_raise(JSON::Schema::ValueError){ 929 | JSON::Schema.validate(item, {"disallow"=>"array"}) 930 | } 931 | end 932 | [1.2, "bad", {"test"=>"blah"}, 1234, nil, true].each do |item| 933 | assert_nothing_raised{ 934 | JSON::Schema.validate(item, {"disallow"=>"array"}) 935 | } 936 | end 937 | 938 | # object phase 939 | [{"blah"=>"test"}, {"this"=>{"blah"=>"test"}}, {1=>2, 10=>20}].each do |item| 940 | assert_raise(JSON::Schema::ValueError){ 941 | JSON::Schema.validate(item, {"disallow"=>"object"}) 942 | } 943 | end 944 | [1.2, "bad", 123, [32, 49], nil, true].each do |item| 945 | assert_nothing_raised{ 946 | JSON::Schema.validate(item, {"disallow"=>"object"}) 947 | } 948 | end 949 | 950 | # boolean phase 951 | [true, false].each do |item| 952 | assert_raise(JSON::Schema::ValueError){ 953 | JSON::Schema.validate(item, {"disallow"=>"boolean"}) 954 | } 955 | end 956 | [1.2, "False", {"test" => "blah"}, [32, 49], nil, 1, 0].each do |item| 957 | assert_nothing_raised{ 958 | JSON::Schema.validate(item, {"disallow"=>"boolean"}) 959 | } 960 | end 961 | 962 | # number phase 963 | [1.2, 89.42, 48.5224242, 32, 49, 42.24324].each do |item| 964 | assert_raise(JSON::Schema::ValueError){ 965 | JSON::Schema.validate(item, {"disallow"=>"number"}) 966 | } 967 | end 968 | ["bad", {"test"=>"blah"}, [32.42, 494242], nil, true].each do |item| 969 | assert_nothing_raised{ 970 | JSON::Schema.validate(item, {"disallow"=>"number"}) 971 | } 972 | end 973 | 974 | # integer phase 975 | [1, 89, 48, 32, 49, 42].each do |item| 976 | assert_raise(JSON::Schema::ValueError){ 977 | JSON::Schema.validate(item, {"disallow"=>"integer"}) 978 | } 979 | end 980 | [1.2, "bad", {"test" => "blah"}, [32, 49], nil, true].each do |item| 981 | assert_nothing_raised{ 982 | JSON::Schema.validate(item, {"disallow"=>"integer"}) 983 | } 984 | end 985 | 986 | # string phase 987 | ["surrender?", "nuts!", "ok", "@hsuha", "\'ok?\'", "blah"].each do |item| 988 | assert_raise(JSON::Schema::ValueError){ 989 | JSON::Schema.validate(item, {"disallow"=>"string"}) 990 | } 991 | end 992 | [1.2, 1, {"test" => "blah"}, [32, 49], nil, true].each do |item| 993 | assert_nothing_raised{ 994 | JSON::Schema.validate(item, {"disallow"=>"string"}) 995 | } 996 | end 997 | end 998 | end 999 | 1000 | --------------------------------------------------------------------------------