File: custom_format_test.rb

package info (click to toggle)
ruby-json-schema 6.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 960 kB
  • sloc: ruby: 6,373; makefile: 4
file content (137 lines) | stat: -rw-r--r-- 5,733 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
require File.expand_path('support/test_helper', __dir__)

class CustomFormatTest < Minitest::Test
  def setup
    @all_versions = ['draft1', 'draft2', 'draft3', 'draft4', 'draft6', nil]
    @format_proc = ->(value) { raise JSON::Schema::CustomFormatError, 'must be 42' unless value == '42' }
    @schema_6 = {
      '$schema' => 'http://json-schema.org/draft-06/schema#',
      'properties' => {
        'a' => {
          'type' => 'string',
          'format' => 'custom',
        },
      },
    }
    @schema_4 = @schema_6.clone
    @schema_4['$schema'] = 'http://json-schema.org/draft-04/schema#'
    @schema_3 = @schema_6.clone
    @schema_3['$schema'] = 'http://json-schema.org/draft-03/schema#'
    @schema_2 = @schema_6.clone
    @schema_2['$schema'] = 'http://json-schema.org/draft-02/schema#'
    @schema_1 = @schema_6.clone
    @schema_1['$schema'] = 'http://json-schema.org/draft-01/schema#'
    @default = @schema_6.clone
    @default.delete('$schema')
    @schemas = {
      'draft1' => @schema_1,
      'draft2' => @schema_2,
      'draft3' => @schema_3,
      'draft4' => @schema_4,
      'draft6' => @schema_6,
      nil => @default,
    }
    JSON::Validator.restore_default_formats
  end

  def test_single_registration
    @all_versions.each do |version|
      assert_nil(JSON::Validator.validator_for_name(version).formats['custom'], "Format 'custom' for #{version || 'default'} should be nil")
      JSON::Validator.register_format_validator('custom', @format_proc, [version])

      assert_kind_of(JSON::Schema::CustomFormat, JSON::Validator.validator_for_name(version).formats['custom'], "Format 'custom' should be registered for #{version || 'default'}")
      (@all_versions - [version]).each do |other_version|
        assert_nil(JSON::Validator.validator_for_name(other_version).formats['custom'], "Format 'custom' should still be nil for #{other_version || 'default'}")
      end
      JSON::Validator.deregister_format_validator('custom', [version])

      assert_nil(JSON::Validator.validator_for_name(version).formats['custom'], "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_kind_of(JSON::Schema::CustomFormat, JSON::Validator.validator_for_name(version).formats['custom'], "Format 'custom' should be registered for #{version || 'default'}")
    end
    JSON::Validator.restore_default_formats

    @all_versions.each do |version|
      assert_nil(JSON::Validator.validator_for_name(version).formats['custom'], "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_kind_of(JSON::Schema::CustomFormat, JSON::Validator.validator_for_name(version).formats['custom'], "Format 'custom' should be registered for #{version || 'default'}")
    end
    assert_nil(JSON::Validator.validator_for_name(unregistered_version).formats['custom'], "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(1, errors.count)
      assert_match(%r{The property '#/a' must be 42 in schema}, errors.first, "#{prefix} records format error")

      errors_as_objects = JSON::Validator.fully_validate(schema, data, errors_as_objects: true)

      assert_match('CustomFormat', errors_as_objects.first[:failed_attribute], "#{prefix} tags failed attribute")

      data['a'] = 23
      errors = JSON::Validator.fully_validate(schema, data)

      assert_equal(1, errors.count)
      assert_match(%r{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 overridden 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