# encoding: utf-8 require File.expand_path('../support/test_helper', __FILE__) class CustomFormatTest < Minitest::Test def setup @all_versions = ['draft1', 'draft2', 'draft3', 'draft4', 'draft6', nil] @format_proc = lambda { |value| raise JSON::Schema::CustomFormatError.new("must be 42") unless value == "42" } @schema_6 = { "$schema" => "http://json-schema.org/draft/schema#", "properties" => { "a" => { "type" => "string", "format" => "custom", }, } } @schema_4 = @schema_6.clone @schema_4["$schema"] = "http://json-schema.org/draft-04/schema#" @schema_3 = @schema_6.clone @schema_3["$schema"] = "http://json-schema.org/draft-03/schema#" @schema_2 = @schema_6.clone @schema_2["$schema"] = "http://json-schema.org/draft-02/schema#" @schema_1 = @schema_6.clone @schema_1["$schema"] = "http://json-schema.org/draft-01/schema#" @default = @schema_6.clone @default.delete("$schema") @schemas = { "draft1" => @schema_1, "draft2" => @schema_2, "draft3" => @schema_3, "draft4" => @schema_4, "draft6" => @schema_6, nil => @default, } JSON::Validator.restore_default_formats end def test_single_registration @all_versions.each do |version| assert(JSON::Validator.validator_for_name(version).formats['custom'].nil?, "Format 'custom' for #{version || 'default'} should be nil") JSON::Validator.register_format_validator("custom", @format_proc, [version]) assert(JSON::Validator.validator_for_name(version).formats['custom'].is_a?(JSON::Schema::CustomFormat), "Format 'custom' should be registered for #{version || 'default'}") (@all_versions - [version]).each do |other_version| assert(JSON::Validator.validator_for_name(other_version).formats['custom'].nil?, "Format 'custom' should still be nil for #{other_version || 'default'}") end JSON::Validator.deregister_format_validator("custom", [version]) assert(JSON::Validator.validator_for_name(version).formats['custom'].nil?, "Format 'custom' should be deregistered for #{version || 'default'}") end end def test_register_for_all_by_default JSON::Validator.register_format_validator("custom", @format_proc) @all_versions.each do |version| assert(JSON::Validator.validator_for_name(version).formats['custom'].is_a?(JSON::Schema::CustomFormat), "Format 'custom' should be registered for #{version || 'default'}") end JSON::Validator.restore_default_formats @all_versions.each do |version| assert(JSON::Validator.validator_for_name(version).formats['custom'].nil?, "Format 'custom' should still be nil for #{version || 'default'}") end end def test_multi_registration unregistered_version = @all_versions.delete("draft1") JSON::Validator.register_format_validator("custom", @format_proc, @all_versions) @all_versions.each do |version| assert(JSON::Validator.validator_for_name(version).formats['custom'].is_a?(JSON::Schema::CustomFormat), "Format 'custom' should be registered for #{version || 'default'}") end assert(JSON::Validator.validator_for_name(unregistered_version).formats['custom'].nil?, "Format 'custom' should still be nil for #{unregistered_version}") end def test_format_validation @all_versions.each do |version| data = { "a" => "23" } schema = @schemas[version] prefix = "Validation for '#{version || 'default'}'" assert(JSON::Validator.validate(schema, data), "#{prefix} succeeds with no 'custom' format validator registered") JSON::Validator.register_format_validator("custom", @format_proc, [version]) data["a"] = "42" assert(JSON::Validator.validate(schema, data), "#{prefix} succeeds with 'custom' format validator and correct data") data["a"] = "23" assert(!JSON::Validator.validate(schema, data), "#{prefix} fails with 'custom' format validator and wrong data") errors = JSON::Validator.fully_validate(schema, data) assert_equal(errors.count, 1) assert_match(/The property '#\/a' must be 42 in schema/, errors.first, "#{prefix} records format error") data["a"] = 23 errors = JSON::Validator.fully_validate(schema, data) assert_equal(errors.count, 1) assert_match(/The property '#\/a' of type integer did not match the following type: string/i, errors.first, "#{prefix} records no format error on type mismatch") end end def test_override_default_format @all_versions.each do |version| data = { "a" => "2001:db8:85a3:0:0:8a2e:370:7334" } schema = @schemas[version] schema["properties"]["a"]["format"] = "ipv6" prefix = "Validation for '#{version || 'default'}'" assert(JSON::Validator.validate(schema, data), "#{prefix} succeeds for default format with correct data") data["a"] = "no_ip6_address" assert(!JSON::Validator.validate(schema, data), "#{prefix} fails for default format and wrong data") data["a"] = "42" JSON::Validator.register_format_validator("ipv6", @format_proc, [version]) assert(JSON::Validator.validate(schema, data), "#{prefix} succeeds with overriden default format and correct data") JSON::Validator.deregister_format_validator("ipv6", [version]) data["a"] = "2001:db8:85a3:0:0:8a2e:370:7334" assert(JSON::Validator.validate(schema, data), "#{prefix} restores the default format on deregistration") end end end