avro-salsify-fork 1.9.0.3 → 1.9.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Manifest +2 -0
- data/Rakefile +1 -1
- data/avro-salsify-fork.gemspec +7 -7
- data/lib/avro.rb +1 -0
- data/lib/avro/schema.rb +4 -39
- data/lib/avro/schema_validator.rb +194 -0
- data/test/test_schema.rb +28 -28
- data/test/test_schema_validator.rb +402 -0
- metadata +7 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4148d1a482eea909deae7631c18e93db4a7907c2
|
|
4
|
+
data.tar.gz: 70e111ad5d85ee5ca788b8385fed629d4f37fb3b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e85db5cae3501913da2497112689d8fa433bf1d48d7f937842b0927deda3d55eaf9c4beb0b26b274cb2d8fac79bdfc820e5e343ec774ddc0a14d508dca7a8105
|
|
7
|
+
data.tar.gz: bbe69d3e6679d4f2c20aea2ca4dc09d63f30b1a75dd40de60b390e500f272a70c7aa34d904f83479965c730c40bdab61846eadbf5ff3f46bceb260440665c912
|
data/Manifest
CHANGED
|
@@ -14,6 +14,7 @@ lib/avro/protocol.rb
|
|
|
14
14
|
lib/avro/schema.rb
|
|
15
15
|
lib/avro/schema_compatibility.rb
|
|
16
16
|
lib/avro/schema_normalization.rb
|
|
17
|
+
lib/avro/schema_validator.rb
|
|
17
18
|
test/case_finder.rb
|
|
18
19
|
test/random_data.rb
|
|
19
20
|
test/sample_ipc_client.rb
|
|
@@ -29,5 +30,6 @@ test/test_protocol.rb
|
|
|
29
30
|
test/test_schema.rb
|
|
30
31
|
test/test_schema_compatibility.rb
|
|
31
32
|
test/test_schema_normalization.rb
|
|
33
|
+
test/test_schema_validator.rb
|
|
32
34
|
test/test_socket_transport.rb
|
|
33
35
|
test/tool.rb
|
data/Rakefile
CHANGED
data/avro-salsify-fork.gemspec
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
|
-
# stub: avro-salsify-fork 1.9.0.
|
|
2
|
+
# stub: avro-salsify-fork 1.9.0.4 ruby lib
|
|
3
3
|
|
|
4
4
|
Gem::Specification.new do |s|
|
|
5
5
|
s.name = "avro-salsify-fork".freeze
|
|
6
|
-
s.version = "1.9.0.
|
|
6
|
+
s.version = "1.9.0.4"
|
|
7
7
|
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2".freeze) if s.respond_to? :required_rubygems_version=
|
|
9
9
|
s.require_paths = ["lib".freeze]
|
|
10
10
|
s.authors = ["Apache Software Foundation / Salsify Engineering".freeze]
|
|
11
|
-
s.date = "
|
|
11
|
+
s.date = "2017-01-30"
|
|
12
12
|
s.description = "Avro is a data serialization and RPC format.\nThis release contains the changes submitted in https://github.com/apache/avro/pull/116\nto support logical types in the Ruby gem.".freeze
|
|
13
13
|
s.email = "engineering@salsify.com".freeze
|
|
14
|
-
s.extra_rdoc_files = ["CHANGELOG".freeze, "LICENSE".freeze, "lib/avro.rb".freeze, "lib/avro/data_file.rb".freeze, "lib/avro/io.rb".freeze, "lib/avro/ipc.rb".freeze, "lib/avro/logical_types.rb".freeze, "lib/avro/protocol.rb".freeze, "lib/avro/schema.rb".freeze, "lib/avro/schema_compatibility.rb".freeze, "lib/avro/schema_normalization.rb".freeze]
|
|
15
|
-
s.files = ["CHANGELOG".freeze, "LICENSE".freeze, "Manifest".freeze, "NOTICE".freeze, "Rakefile".freeze, "avro-salsify-fork.gemspec".freeze, "avro.gemspec".freeze, "interop/test_interop.rb".freeze, "lib/avro.rb".freeze, "lib/avro/data_file.rb".freeze, "lib/avro/io.rb".freeze, "lib/avro/ipc.rb".freeze, "lib/avro/logical_types.rb".freeze, "lib/avro/protocol.rb".freeze, "lib/avro/schema.rb".freeze, "lib/avro/schema_compatibility.rb".freeze, "lib/avro/schema_normalization.rb".freeze, "test/case_finder.rb".freeze, "test/random_data.rb".freeze, "test/sample_ipc_client.rb".freeze, "test/sample_ipc_http_client.rb".freeze, "test/sample_ipc_http_server.rb".freeze, "test/sample_ipc_server.rb".freeze, "test/test_datafile.rb".freeze, "test/test_fingerprints.rb".freeze, "test/test_help.rb".freeze, "test/test_io.rb".freeze, "test/test_logical_types.rb".freeze, "test/test_protocol.rb".freeze, "test/test_schema.rb".freeze, "test/test_schema_compatibility.rb".freeze, "test/test_schema_normalization.rb".freeze, "test/test_socket_transport.rb".freeze, "test/tool.rb".freeze]
|
|
14
|
+
s.extra_rdoc_files = ["CHANGELOG".freeze, "LICENSE".freeze, "lib/avro.rb".freeze, "lib/avro/data_file.rb".freeze, "lib/avro/io.rb".freeze, "lib/avro/ipc.rb".freeze, "lib/avro/logical_types.rb".freeze, "lib/avro/protocol.rb".freeze, "lib/avro/schema.rb".freeze, "lib/avro/schema_compatibility.rb".freeze, "lib/avro/schema_normalization.rb".freeze, "lib/avro/schema_validator.rb".freeze]
|
|
15
|
+
s.files = ["CHANGELOG".freeze, "LICENSE".freeze, "Manifest".freeze, "NOTICE".freeze, "Rakefile".freeze, "avro-salsify-fork.gemspec".freeze, "avro.gemspec".freeze, "interop/test_interop.rb".freeze, "lib/avro.rb".freeze, "lib/avro/data_file.rb".freeze, "lib/avro/io.rb".freeze, "lib/avro/ipc.rb".freeze, "lib/avro/logical_types.rb".freeze, "lib/avro/protocol.rb".freeze, "lib/avro/schema.rb".freeze, "lib/avro/schema_compatibility.rb".freeze, "lib/avro/schema_normalization.rb".freeze, "lib/avro/schema_validator.rb".freeze, "test/case_finder.rb".freeze, "test/random_data.rb".freeze, "test/sample_ipc_client.rb".freeze, "test/sample_ipc_http_client.rb".freeze, "test/sample_ipc_http_server.rb".freeze, "test/sample_ipc_server.rb".freeze, "test/test_datafile.rb".freeze, "test/test_fingerprints.rb".freeze, "test/test_help.rb".freeze, "test/test_io.rb".freeze, "test/test_logical_types.rb".freeze, "test/test_protocol.rb".freeze, "test/test_schema.rb".freeze, "test/test_schema_compatibility.rb".freeze, "test/test_schema_normalization.rb".freeze, "test/test_schema_validator.rb".freeze, "test/test_socket_transport.rb".freeze, "test/tool.rb".freeze]
|
|
16
16
|
s.homepage = "https://github.com/salsify/avro".freeze
|
|
17
17
|
s.licenses = ["Apache License 2.0 (Apache-2.0)".freeze]
|
|
18
18
|
s.rdoc_options = ["--line-numbers".freeze, "--title".freeze, "Avro-salsify-fork".freeze]
|
|
19
19
|
s.rubyforge_project = "avro-salsify-fork".freeze
|
|
20
|
-
s.rubygems_version = "2.6.
|
|
20
|
+
s.rubygems_version = "2.6.8".freeze
|
|
21
21
|
s.summary = "Apache Avro for Ruby with logical types patch".freeze
|
|
22
|
-
s.test_files = ["test/test_datafile.rb".freeze, "test/test_fingerprints.rb".freeze, "test/test_help.rb".freeze, "test/test_io.rb".freeze, "test/test_logical_types.rb".freeze, "test/test_protocol.rb".freeze, "test/test_schema.rb".freeze, "test/test_schema_compatibility.rb".freeze, "test/test_schema_normalization.rb".freeze, "test/test_socket_transport.rb".freeze]
|
|
22
|
+
s.test_files = ["test/test_datafile.rb".freeze, "test/test_fingerprints.rb".freeze, "test/test_help.rb".freeze, "test/test_io.rb".freeze, "test/test_logical_types.rb".freeze, "test/test_protocol.rb".freeze, "test/test_schema.rb".freeze, "test/test_schema_compatibility.rb".freeze, "test/test_schema_normalization.rb".freeze, "test/test_schema_validator.rb".freeze, "test/test_socket_transport.rb".freeze]
|
|
23
23
|
|
|
24
24
|
if s.respond_to? :specification_version then
|
|
25
25
|
s.specification_version = 4
|
data/lib/avro.rb
CHANGED
data/lib/avro/schema.rb
CHANGED
|
@@ -95,45 +95,10 @@ module Avro
|
|
|
95
95
|
|
|
96
96
|
# Determine if a ruby datum is an instance of a schema
|
|
97
97
|
def self.validate(expected_schema, logical_datum, encoded = false)
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
case expected_schema.type_sym
|
|
105
|
-
when :null
|
|
106
|
-
datum.nil?
|
|
107
|
-
when :boolean
|
|
108
|
-
datum == true || datum == false
|
|
109
|
-
when :string, :bytes
|
|
110
|
-
datum.is_a? String
|
|
111
|
-
when :int
|
|
112
|
-
(datum.is_a?(Fixnum) || datum.is_a?(Bignum)) &&
|
|
113
|
-
(INT_MIN_VALUE <= datum) && (datum <= INT_MAX_VALUE)
|
|
114
|
-
when :long
|
|
115
|
-
(datum.is_a?(Fixnum) || datum.is_a?(Bignum)) &&
|
|
116
|
-
(LONG_MIN_VALUE <= datum) && (datum <= LONG_MAX_VALUE)
|
|
117
|
-
when :float, :double
|
|
118
|
-
datum.is_a?(Float) || datum.is_a?(Fixnum) || datum.is_a?(Bignum)
|
|
119
|
-
when :fixed
|
|
120
|
-
datum.is_a?(String) && datum.bytesize == expected_schema.size
|
|
121
|
-
when :enum
|
|
122
|
-
expected_schema.symbols.include? datum
|
|
123
|
-
when :array
|
|
124
|
-
datum.is_a?(Array) &&
|
|
125
|
-
datum.all?{|d| validate(expected_schema.items, d) }
|
|
126
|
-
when :map
|
|
127
|
-
datum.keys.all?{|k| k.is_a? String } &&
|
|
128
|
-
datum.values.all?{|v| validate(expected_schema.values, v) }
|
|
129
|
-
when :union
|
|
130
|
-
expected_schema.schemas.any?{|s| validate(s, datum) }
|
|
131
|
-
when :record, :error, :request
|
|
132
|
-
datum.is_a?(Hash) &&
|
|
133
|
-
expected_schema.fields.all?{|f| validate(f.type, datum[f.name]) }
|
|
134
|
-
else
|
|
135
|
-
raise "you suck #{expected_schema.inspect} is not allowed."
|
|
136
|
-
end
|
|
98
|
+
SchemaValidator.validate!(expected_schema, logical_datum, encoded)
|
|
99
|
+
true
|
|
100
|
+
rescue SchemaValidator::ValidationError
|
|
101
|
+
false
|
|
137
102
|
end
|
|
138
103
|
|
|
139
104
|
def initialize(type, logical_type=nil)
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
|
2
|
+
# or more contributor license agreements. See the NOTICE file
|
|
3
|
+
# distributed with this work for additional information
|
|
4
|
+
# regarding copyright ownership. The ASF licenses this file
|
|
5
|
+
# to you under the Apache License, Version 2.0 (the
|
|
6
|
+
# "License"); you may not use this file except in compliance
|
|
7
|
+
# with the License. You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
module Avro
|
|
18
|
+
class SchemaValidator
|
|
19
|
+
ROOT_IDENTIFIER = '.'.freeze
|
|
20
|
+
PATH_SEPARATOR = '.'.freeze
|
|
21
|
+
INT_RANGE = Schema::INT_MIN_VALUE..Schema::INT_MAX_VALUE
|
|
22
|
+
LONG_RANGE = Schema::LONG_MIN_VALUE..Schema::LONG_MAX_VALUE
|
|
23
|
+
COMPLEX_TYPES = [:array, :error, :map, :record, :request]
|
|
24
|
+
|
|
25
|
+
class Result
|
|
26
|
+
attr_reader :errors
|
|
27
|
+
|
|
28
|
+
def initialize
|
|
29
|
+
@errors = []
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def <<(error)
|
|
33
|
+
@errors << error
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def add_error(path, message)
|
|
37
|
+
self << "at #{path} #{message}"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def failure?
|
|
41
|
+
@errors.any?
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def to_s
|
|
45
|
+
errors.join("\n")
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
class ValidationError < StandardError
|
|
50
|
+
attr_reader :result
|
|
51
|
+
|
|
52
|
+
def initialize(result = Result.new)
|
|
53
|
+
@result = result
|
|
54
|
+
super
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def to_s
|
|
58
|
+
result.to_s
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
TypeMismatchError = Class.new(ValidationError)
|
|
63
|
+
|
|
64
|
+
class << self
|
|
65
|
+
def validate!(expected_schema, logical_datum, encoded = false)
|
|
66
|
+
result = Result.new
|
|
67
|
+
validate_recursive(expected_schema, logical_datum, ROOT_IDENTIFIER, result, encoded)
|
|
68
|
+
fail ValidationError, result if result.failure?
|
|
69
|
+
result
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
def validate_recursive(expected_schema, logical_datum, path, result, encoded = false)
|
|
75
|
+
datum = if encoded
|
|
76
|
+
logical_datum
|
|
77
|
+
else
|
|
78
|
+
expected_schema.type_adapter.encode(logical_datum) rescue nil
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
case expected_schema.type_sym
|
|
82
|
+
when :null
|
|
83
|
+
fail TypeMismatchError unless datum.nil?
|
|
84
|
+
when :boolean
|
|
85
|
+
fail TypeMismatchError unless [true, false].include?(datum)
|
|
86
|
+
when :string, :bytes
|
|
87
|
+
fail TypeMismatchError unless datum.is_a?(String)
|
|
88
|
+
when :int
|
|
89
|
+
fail TypeMismatchError unless datum.is_a?(Fixnum) || datum.is_a?(Bignum)
|
|
90
|
+
result.add_error(path, "out of bound value #{datum}") unless INT_RANGE.cover?(datum)
|
|
91
|
+
when :long
|
|
92
|
+
fail TypeMismatchError unless datum.is_a?(Fixnum) || datum.is_a?(Bignum)
|
|
93
|
+
result.add_error(path, "out of bound value #{datum}") unless LONG_RANGE.cover?(datum)
|
|
94
|
+
when :float, :double
|
|
95
|
+
fail TypeMismatchError unless [Float, Fixnum, Bignum].any?(&datum.method(:is_a?))
|
|
96
|
+
when :fixed
|
|
97
|
+
if datum.is_a? String
|
|
98
|
+
message = "expected fixed with size #{expected_schema.size}, got \"#{datum}\" with size #{datum.size}"
|
|
99
|
+
result.add_error(path, message) unless datum.bytesize == expected_schema.size
|
|
100
|
+
else
|
|
101
|
+
result.add_error(path, "expected fixed with size #{expected_schema.size}, got #{actual_value_message(datum)}")
|
|
102
|
+
end
|
|
103
|
+
when :enum
|
|
104
|
+
message = "expected enum with values #{expected_schema.symbols}, got #{actual_value_message(datum)}"
|
|
105
|
+
result.add_error(path, message) unless expected_schema.symbols.include?(datum)
|
|
106
|
+
when :array
|
|
107
|
+
validate_array(expected_schema, datum, path, result)
|
|
108
|
+
when :map
|
|
109
|
+
validate_map(expected_schema, datum, path, result)
|
|
110
|
+
when :union
|
|
111
|
+
validate_union(expected_schema, datum, path, result)
|
|
112
|
+
when :record, :error, :request
|
|
113
|
+
fail TypeMismatchError unless datum.is_a?(Hash)
|
|
114
|
+
expected_schema.fields.each do |field|
|
|
115
|
+
deeper_path = deeper_path_for_hash(field.name, path)
|
|
116
|
+
validate_recursive(field.type, datum[field.name], deeper_path, result)
|
|
117
|
+
end
|
|
118
|
+
else
|
|
119
|
+
fail "Unexpected schema type #{expected_schema.type_sym} #{expected_schema.inspect}"
|
|
120
|
+
end
|
|
121
|
+
rescue TypeMismatchError
|
|
122
|
+
result.add_error(path, "expected type #{expected_schema.type_sym}, got #{actual_value_message(datum)}")
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def validate_array(expected_schema, datum, path, result)
|
|
126
|
+
fail TypeMismatchError unless datum.is_a?(Array)
|
|
127
|
+
datum.each_with_index do |d, i|
|
|
128
|
+
validate_recursive(expected_schema.items, d, path + "[#{i}]", result)
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def validate_map(expected_schema, datum, path, result)
|
|
133
|
+
datum.keys.each do |k|
|
|
134
|
+
result.add_error(path, "unexpected key type '#{ruby_to_avro_type(k.class)}' in map") unless k.is_a?(String)
|
|
135
|
+
end
|
|
136
|
+
datum.each do |k, v|
|
|
137
|
+
deeper_path = deeper_path_for_hash(k, path)
|
|
138
|
+
validate_recursive(expected_schema.values, v, deeper_path, result)
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def validate_union(expected_schema, datum, path, result)
|
|
143
|
+
if expected_schema.schemas.size == 1
|
|
144
|
+
validate_recursive(expected_schema.schemas.first, datum, path, result)
|
|
145
|
+
return
|
|
146
|
+
end
|
|
147
|
+
types_and_results = validate_possible_types(datum, expected_schema, path)
|
|
148
|
+
failures, successes = types_and_results.partition { |r| r[:result].failure? }
|
|
149
|
+
return if successes.any?
|
|
150
|
+
complex_type_failed = failures.detect { |r| COMPLEX_TYPES.include?(r[:type]) }
|
|
151
|
+
if complex_type_failed
|
|
152
|
+
complex_type_failed[:result].errors.each { |error| result << error }
|
|
153
|
+
else
|
|
154
|
+
types = expected_schema.schemas.map { |s| "'#{s.type_sym}'" }.join(', ')
|
|
155
|
+
result.add_error(path, "expected union of [#{types}], got #{actual_value_message(datum)}")
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def validate_possible_types(datum, expected_schema, path)
|
|
160
|
+
expected_schema.schemas.map do |schema|
|
|
161
|
+
result = Result.new
|
|
162
|
+
validate_recursive(schema, datum, path, result)
|
|
163
|
+
{ type: schema.type_sym, result: result }
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def deeper_path_for_hash(sub_key, path)
|
|
168
|
+
"#{path}#{PATH_SEPARATOR}#{sub_key}".squeeze(PATH_SEPARATOR)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
private
|
|
172
|
+
|
|
173
|
+
def actual_value_message(value)
|
|
174
|
+
avro_type = ruby_to_avro_type(value.class)
|
|
175
|
+
if value.nil?
|
|
176
|
+
avro_type
|
|
177
|
+
else
|
|
178
|
+
"#{avro_type} with value #{value.inspect}"
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def ruby_to_avro_type(ruby_class)
|
|
183
|
+
{
|
|
184
|
+
NilClass => 'null',
|
|
185
|
+
String => 'string',
|
|
186
|
+
Fixnum => 'int',
|
|
187
|
+
Bignum => 'long',
|
|
188
|
+
Float => 'float',
|
|
189
|
+
Hash => 'record'
|
|
190
|
+
}.fetch(ruby_class, ruby_class)
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
data/test/test_schema.rb
CHANGED
|
@@ -27,13 +27,13 @@ class TestSchema < Test::Unit::TestCase
|
|
|
27
27
|
]}
|
|
28
28
|
SCHEMA
|
|
29
29
|
|
|
30
|
-
assert_equal schema.name
|
|
31
|
-
assert_equal schema.fullname
|
|
30
|
+
assert_equal 'OuterRecord', schema.name
|
|
31
|
+
assert_equal 'OuterRecord', schema.fullname
|
|
32
32
|
assert_nil schema.namespace
|
|
33
33
|
|
|
34
34
|
schema.fields.each do |field|
|
|
35
|
-
assert_equal field.type.name
|
|
36
|
-
assert_equal field.type.fullname
|
|
35
|
+
assert_equal 'InnerRecord', field.type.name
|
|
36
|
+
assert_equal 'InnerRecord', field.type.fullname
|
|
37
37
|
assert_nil field.type.namespace
|
|
38
38
|
end
|
|
39
39
|
end
|
|
@@ -50,13 +50,13 @@ class TestSchema < Test::Unit::TestCase
|
|
|
50
50
|
]}
|
|
51
51
|
SCHEMA
|
|
52
52
|
|
|
53
|
-
assert_equal schema.name
|
|
54
|
-
assert_equal
|
|
55
|
-
assert_equal
|
|
53
|
+
assert_equal 'OuterRecord', schema.name
|
|
54
|
+
assert_equal 'my.name.space.OuterRecord', schema.fullname
|
|
55
|
+
assert_equal 'my.name.space', schema.namespace
|
|
56
56
|
schema.fields.each do |field|
|
|
57
|
-
assert_equal field.type.name
|
|
58
|
-
assert_equal
|
|
59
|
-
assert_equal
|
|
57
|
+
assert_equal 'InnerRecord', field.type.name
|
|
58
|
+
assert_equal 'my.name.space.InnerRecord', field.type.fullname
|
|
59
|
+
assert_equal 'my.name.space', field.type.namespace
|
|
60
60
|
end
|
|
61
61
|
end
|
|
62
62
|
|
|
@@ -71,13 +71,13 @@ class TestSchema < Test::Unit::TestCase
|
|
|
71
71
|
]}
|
|
72
72
|
SCHEMA
|
|
73
73
|
|
|
74
|
-
assert_equal schema.name
|
|
75
|
-
assert_equal
|
|
76
|
-
assert_equal
|
|
74
|
+
assert_equal 'OuterRecord', schema.name
|
|
75
|
+
assert_equal 'my.name.space.OuterRecord', schema.fullname
|
|
76
|
+
assert_equal 'my.name.space', schema.namespace
|
|
77
77
|
schema.fields.each do |field|
|
|
78
|
-
assert_equal field.type.name
|
|
79
|
-
assert_equal
|
|
80
|
-
assert_equal
|
|
78
|
+
assert_equal 'InnerEnum', field.type.name
|
|
79
|
+
assert_equal 'my.name.space.InnerEnum', field.type.fullname
|
|
80
|
+
assert_equal 'my.name.space', field.type.namespace
|
|
81
81
|
end
|
|
82
82
|
end
|
|
83
83
|
|
|
@@ -96,18 +96,18 @@ class TestSchema < Test::Unit::TestCase
|
|
|
96
96
|
]}
|
|
97
97
|
SCHEMA
|
|
98
98
|
|
|
99
|
-
assert_equal schema.name
|
|
100
|
-
assert_equal
|
|
101
|
-
assert_equal schema.namespace
|
|
99
|
+
assert_equal 'OuterRecord', schema.name
|
|
100
|
+
assert_equal 'outer.OuterRecord', schema.fullname
|
|
101
|
+
assert_equal 'outer', schema.namespace
|
|
102
102
|
middle = schema.fields.first.type
|
|
103
|
-
assert_equal middle.name
|
|
104
|
-
assert_equal middle.
|
|
105
|
-
assert_equal middle
|
|
103
|
+
assert_equal 'MiddleRecord', middle.name
|
|
104
|
+
assert_equal 'middle.MiddleRecord', middle.fullname
|
|
105
|
+
assert_equal 'middle', middle.namespace
|
|
106
106
|
inner = middle.fields.first.type
|
|
107
|
-
assert_equal inner.name
|
|
108
|
-
assert_equal
|
|
109
|
-
assert_equal inner.namespace
|
|
110
|
-
assert_equal inner.fields.first.type
|
|
107
|
+
assert_equal 'InnerRecord', inner.name
|
|
108
|
+
assert_equal 'middle.InnerRecord', inner.fullname
|
|
109
|
+
assert_equal 'middle', inner.namespace
|
|
110
|
+
assert_equal middle, inner.fields.first.type
|
|
111
111
|
end
|
|
112
112
|
|
|
113
113
|
def test_to_avro_includes_namespaces
|
|
@@ -120,7 +120,7 @@ class TestSchema < Test::Unit::TestCase
|
|
|
120
120
|
]}
|
|
121
121
|
SCHEMA
|
|
122
122
|
|
|
123
|
-
assert_equal
|
|
123
|
+
assert_equal({
|
|
124
124
|
'type' => 'record', 'name' => 'OuterRecord', 'namespace' => 'my.name.space',
|
|
125
125
|
'fields' => [
|
|
126
126
|
{'name' => 'definition', 'type' => {
|
|
@@ -129,7 +129,7 @@ class TestSchema < Test::Unit::TestCase
|
|
|
129
129
|
}},
|
|
130
130
|
{'name' => 'reference', 'type' => 'my.name.space.InnerFixed'}
|
|
131
131
|
]
|
|
132
|
-
}
|
|
132
|
+
}, schema.to_avro)
|
|
133
133
|
end
|
|
134
134
|
|
|
135
135
|
def test_to_avro_includes_logical_type
|
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
|
2
|
+
# or more contributor license agreements. See the NOTICE file
|
|
3
|
+
# distributed with this work for additional information
|
|
4
|
+
# regarding copyright ownership. The ASF licenses this file
|
|
5
|
+
# to you under the Apache License, Version 2.0 (the
|
|
6
|
+
# "License"); you may not use this file except in compliance
|
|
7
|
+
# with the License. You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
require 'test_help'
|
|
18
|
+
|
|
19
|
+
class TestSchema < Test::Unit::TestCase
|
|
20
|
+
def validate!(schema, value)
|
|
21
|
+
Avro::SchemaValidator.validate!(schema, value)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def hash_to_schema(hash)
|
|
25
|
+
Avro::Schema.parse(hash.to_json)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def assert_failed_validation(messages)
|
|
29
|
+
error = assert_raise(Avro::SchemaValidator::ValidationError) { yield }
|
|
30
|
+
|
|
31
|
+
assert_messages = [messages].flatten
|
|
32
|
+
result_errors = error.result.errors
|
|
33
|
+
assert_messages.each do |message|
|
|
34
|
+
assert(result_errors.include?(message), "expected '#{message}' to be in '#{result_errors}'")
|
|
35
|
+
end
|
|
36
|
+
assert_equal(assert_messages.size, result_errors.size)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def assert_valid_schema(schema, valid, invalid)
|
|
40
|
+
valid.each do |value|
|
|
41
|
+
assert_nothing_raised { Avro::SchemaValidator.validate!(schema, value) }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
invalid.each do |value|
|
|
45
|
+
assert_raise { Avro::SchemaValidator.validate!(schema, value) }
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def test_validate_nil
|
|
50
|
+
schema = hash_to_schema(type: 'null', name: 'name')
|
|
51
|
+
|
|
52
|
+
assert_nothing_raised { validate!(schema, nil) }
|
|
53
|
+
|
|
54
|
+
assert_failed_validation('at . expected type null, got int with value 1') do
|
|
55
|
+
validate!(schema, 1)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def test_validate_boolean
|
|
60
|
+
schema = hash_to_schema(type: 'boolean', name: 'name')
|
|
61
|
+
|
|
62
|
+
assert_nothing_raised { validate!(schema, true) }
|
|
63
|
+
assert_nothing_raised { validate!(schema, false) }
|
|
64
|
+
|
|
65
|
+
assert_failed_validation('at . expected type boolean, got int with value 1') do
|
|
66
|
+
validate!(schema, 1)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
assert_failed_validation('at . expected type boolean, got null') do
|
|
70
|
+
validate!(schema, nil)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def test_fixed_size_string
|
|
75
|
+
schema = hash_to_schema(type: 'fixed', name: 'some', size: 3)
|
|
76
|
+
|
|
77
|
+
assert_nothing_raised { validate!(schema, 'baf') }
|
|
78
|
+
|
|
79
|
+
assert_failed_validation('at . expected fixed with size 3, got "some" with size 4') do
|
|
80
|
+
validate!(schema, 'some')
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
assert_failed_validation('at . expected fixed with size 3, got null') do
|
|
84
|
+
validate!(schema, nil)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def test_original_validate_nil
|
|
89
|
+
schema = hash_to_schema(type: 'null', name: 'name')
|
|
90
|
+
|
|
91
|
+
assert_valid_schema(schema, [nil], ['something'])
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def test_original_validate_boolean
|
|
95
|
+
schema = hash_to_schema(type: 'boolean', name: 'name')
|
|
96
|
+
|
|
97
|
+
assert_valid_schema(schema, [true, false], [nil, 1])
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def test_validate_string
|
|
101
|
+
schema = hash_to_schema(type: 'string', name: 'name')
|
|
102
|
+
|
|
103
|
+
assert_valid_schema(schema, ['string'], [nil, 1])
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def test_validate_bytes
|
|
107
|
+
schema = hash_to_schema(type: 'bytes', name: 'name')
|
|
108
|
+
|
|
109
|
+
assert_valid_schema(schema, ['string'], [nil, 1])
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def test_validate_int
|
|
113
|
+
schema = hash_to_schema(type: 'int', name: 'name')
|
|
114
|
+
|
|
115
|
+
assert_valid_schema(
|
|
116
|
+
schema,
|
|
117
|
+
[Avro::Schema::INT_MIN_VALUE, Avro::Schema::INT_MAX_VALUE, 1],
|
|
118
|
+
[Avro::Schema::LONG_MIN_VALUE, Avro::Schema::LONG_MAX_VALUE, 'string']
|
|
119
|
+
)
|
|
120
|
+
assert_failed_validation('at . out of bound value 9223372036854775807') do
|
|
121
|
+
validate!(schema, Avro::Schema::LONG_MAX_VALUE)
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def test_validate_long
|
|
126
|
+
schema = hash_to_schema(type: 'long', name: 'name')
|
|
127
|
+
|
|
128
|
+
assert_valid_schema(schema, [Avro::Schema::LONG_MIN_VALUE, Avro::Schema::LONG_MAX_VALUE, 1], [1.1, 'string'])
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def test_validate_float
|
|
132
|
+
schema = hash_to_schema(type: 'float', name: 'name')
|
|
133
|
+
|
|
134
|
+
assert_valid_schema(schema, [1.1, 1, Avro::Schema::LONG_MAX_VALUE], ['string'])
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def test_validate_double
|
|
138
|
+
schema = hash_to_schema(type: 'double', name: 'name')
|
|
139
|
+
|
|
140
|
+
assert_valid_schema(schema, [1.1, 1, Avro::Schema::LONG_MAX_VALUE], ['string'])
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def test_validate_fixed
|
|
144
|
+
schema = hash_to_schema(type: 'fixed', name: 'name', size: 3)
|
|
145
|
+
|
|
146
|
+
assert_valid_schema(schema, ['abc'], ['ab', 1, 1.1, true])
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def test_validate_original_num
|
|
150
|
+
schema = hash_to_schema(type: 'enum', name: 'name', symbols: %w(a b))
|
|
151
|
+
|
|
152
|
+
assert_valid_schema(schema, ['a', 'b'], ['c'])
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def test_validate_record
|
|
156
|
+
schema = hash_to_schema(type: 'record', name: 'name', fields: [{ type: 'null', name: 'sub' }])
|
|
157
|
+
|
|
158
|
+
assert_valid_schema(schema, [{ 'sub' => nil }], [{ 'sub' => 1 }])
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def test_validate_shallow_record
|
|
162
|
+
schema = hash_to_schema(
|
|
163
|
+
type: 'record', name: 'name', fields: [{ type: 'int', name: 'sub' }]
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
assert_nothing_raised { validate!(schema, 'sub' => 1) }
|
|
167
|
+
|
|
168
|
+
assert_failed_validation('at .sub expected type int, got null') do
|
|
169
|
+
validate!(schema, {})
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
assert_failed_validation('at . expected type record, got float with value 1.2') do
|
|
173
|
+
validate!(schema, 1.2)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
assert_failed_validation('at .sub expected type int, got float with value 1.2') do
|
|
177
|
+
validate!(schema, 'sub' => 1.2)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
assert_failed_validation('at .sub expected type int, got null') do
|
|
181
|
+
validate!(schema, {})
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def test_validate_array
|
|
186
|
+
schema = hash_to_schema(type: 'array',
|
|
187
|
+
name: 'person',
|
|
188
|
+
items: [{ type: 'int', name: 'height' }])
|
|
189
|
+
|
|
190
|
+
assert_nothing_raised { validate!(schema, []) }
|
|
191
|
+
|
|
192
|
+
assert_failed_validation 'at . expected type array, got null' do
|
|
193
|
+
validate!(schema, nil)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
assert_failed_validation('at .[0] expected type int, got null') do
|
|
197
|
+
validate!(schema, [nil])
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
assert_failed_validation('at .[3] expected type int, got string with value "so wrong"') do
|
|
201
|
+
validate!(schema, [1, 3, 9, 'so wrong'])
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def test_validate_enum
|
|
206
|
+
schema = hash_to_schema(type: 'enum',
|
|
207
|
+
name: 'person',
|
|
208
|
+
symbols: %w(one two three))
|
|
209
|
+
|
|
210
|
+
assert_nothing_raised { validate!(schema, 'one') }
|
|
211
|
+
|
|
212
|
+
assert_failed_validation('at . expected enum with values ["one", "two", "three"], got string with value "five"') do
|
|
213
|
+
validate!(schema, 'five')
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def test_validate_union_on_primitive_types
|
|
218
|
+
schema = hash_to_schema(
|
|
219
|
+
name: 'should_not_matter',
|
|
220
|
+
type: 'record',
|
|
221
|
+
fields: [
|
|
222
|
+
{ name: 'what_ever', type: %w(long string) }
|
|
223
|
+
]
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
assert_failed_validation('at .what_ever expected union of [\'long\', \'string\'], got null') {
|
|
227
|
+
validate!(schema, 'what_ever' => nil)
|
|
228
|
+
}
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def test_validate_union_of_nil_and_record_inside_array
|
|
232
|
+
schema = hash_to_schema(
|
|
233
|
+
name: 'this does not matter',
|
|
234
|
+
type: 'record',
|
|
235
|
+
fields: [
|
|
236
|
+
{
|
|
237
|
+
name: 'person',
|
|
238
|
+
type: {
|
|
239
|
+
name: 'person_entry',
|
|
240
|
+
type: 'record',
|
|
241
|
+
fields: [
|
|
242
|
+
{
|
|
243
|
+
name: 'houses',
|
|
244
|
+
type: [
|
|
245
|
+
'null',
|
|
246
|
+
{
|
|
247
|
+
name: 'houses_entry',
|
|
248
|
+
type: 'array',
|
|
249
|
+
items: [
|
|
250
|
+
{
|
|
251
|
+
name: 'house_entry',
|
|
252
|
+
type: 'record',
|
|
253
|
+
fields: [
|
|
254
|
+
{ name: 'number_of_rooms', type: 'long' }
|
|
255
|
+
]
|
|
256
|
+
}
|
|
257
|
+
]
|
|
258
|
+
}
|
|
259
|
+
],
|
|
260
|
+
}
|
|
261
|
+
]
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
]
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
assert_failed_validation('at .person expected type record, got null') {
|
|
268
|
+
validate!(schema, 'not at all' => nil)
|
|
269
|
+
}
|
|
270
|
+
assert_nothing_raised { validate!(schema, 'person' => {}) }
|
|
271
|
+
assert_nothing_raised { validate!(schema, 'person' => { houses: [] }) }
|
|
272
|
+
assert_nothing_raised { validate!(schema, 'person' => { 'houses' => [{ 'number_of_rooms' => 1 }] }) }
|
|
273
|
+
|
|
274
|
+
message = 'at .person.houses[1].number_of_rooms expected type long, got string with value "not valid at all"'
|
|
275
|
+
assert_failed_validation(message) do
|
|
276
|
+
validate!(
|
|
277
|
+
schema,
|
|
278
|
+
'person' => {
|
|
279
|
+
'houses' => [
|
|
280
|
+
{ 'number_of_rooms' => 2 },
|
|
281
|
+
{ 'number_of_rooms' => 'not valid at all' }
|
|
282
|
+
]
|
|
283
|
+
}
|
|
284
|
+
)
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
def test_validate_map
|
|
289
|
+
schema = hash_to_schema(type: 'map',
|
|
290
|
+
name: 'numbers',
|
|
291
|
+
values: [
|
|
292
|
+
{ name: 'some', type: 'int' }
|
|
293
|
+
])
|
|
294
|
+
|
|
295
|
+
assert_nothing_raised { validate!(schema, 'some' => 1) }
|
|
296
|
+
|
|
297
|
+
assert_failed_validation('at .some expected type int, got string with value "nope"') do
|
|
298
|
+
validate!(schema, 'some' => 'nope')
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
assert_failed_validation("at . unexpected key type 'Symbol' in map") do
|
|
302
|
+
validate!(schema, some: 1)
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def test_validate_deep_record
|
|
307
|
+
schema = hash_to_schema(type: 'record',
|
|
308
|
+
name: 'person',
|
|
309
|
+
fields: [
|
|
310
|
+
{
|
|
311
|
+
name: 'head',
|
|
312
|
+
type: {
|
|
313
|
+
name: 'head',
|
|
314
|
+
type: 'record',
|
|
315
|
+
fields: [
|
|
316
|
+
{
|
|
317
|
+
name: 'hair',
|
|
318
|
+
type: {
|
|
319
|
+
name: 'hair',
|
|
320
|
+
type: 'record',
|
|
321
|
+
fields: [
|
|
322
|
+
{
|
|
323
|
+
name: 'color',
|
|
324
|
+
type: 'string'
|
|
325
|
+
}
|
|
326
|
+
]
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
]
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
])
|
|
333
|
+
|
|
334
|
+
assert_nothing_raised { validate!(schema, 'head' => { 'hair' => { 'color' => 'black' } }) }
|
|
335
|
+
|
|
336
|
+
assert_failed_validation('at .head.hair.color expected type string, got null') do
|
|
337
|
+
validate!(schema, 'head' => { 'hair' => { 'color' => nil } })
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
assert_failed_validation('at .head.hair.color expected type string, got null') do
|
|
341
|
+
validate!(schema, 'head' => { 'hair' => {} })
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
assert_failed_validation('at .head.hair expected type record, got null') do
|
|
345
|
+
validate!(schema, 'head' => {})
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
assert_failed_validation('at . expected type record, got null') do
|
|
349
|
+
validate!(schema, nil)
|
|
350
|
+
end
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
def test_validate_deep_record_with_array
|
|
354
|
+
schema = hash_to_schema(type: 'record',
|
|
355
|
+
name: 'fruits',
|
|
356
|
+
fields: [
|
|
357
|
+
{
|
|
358
|
+
name: 'fruits',
|
|
359
|
+
type: {
|
|
360
|
+
name: 'fruits',
|
|
361
|
+
type: 'array',
|
|
362
|
+
items: [
|
|
363
|
+
{
|
|
364
|
+
name: 'fruit',
|
|
365
|
+
type: 'record',
|
|
366
|
+
fields: [
|
|
367
|
+
{ name: 'name', type: 'string' },
|
|
368
|
+
{ name: 'weight', type: 'float' }
|
|
369
|
+
]
|
|
370
|
+
}
|
|
371
|
+
]
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
])
|
|
375
|
+
assert_nothing_raised { validate!(schema, 'fruits' => [{ 'name' => 'apple', 'weight' => 30.2 }]) }
|
|
376
|
+
|
|
377
|
+
assert_failed_validation('at .fruits[0].name expected type string, got null') do
|
|
378
|
+
validate!(schema, 'fruits' => [{ 'name' => nil, 'weight' => 30.2 }])
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
assert_failed_validation('at .fruits expected type array, got int with value 1') do
|
|
382
|
+
validate!(schema, 'fruits' => 1)
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
def test_validate_multiple_errors
|
|
387
|
+
schema = hash_to_schema(type: 'array',
|
|
388
|
+
name: 'ages',
|
|
389
|
+
items: [
|
|
390
|
+
{ type: 'int', name: 'age' }
|
|
391
|
+
])
|
|
392
|
+
|
|
393
|
+
exception = assert_raise(Avro::SchemaValidator::ValidationError) do
|
|
394
|
+
validate!(schema, [nil, 'e'])
|
|
395
|
+
end
|
|
396
|
+
assert_equal 2, exception.result.errors.size
|
|
397
|
+
assert_equal(
|
|
398
|
+
"at .[0] expected type int, got null\nat .[1] expected type int, got string with value \"e\"",
|
|
399
|
+
exception.to_s
|
|
400
|
+
)
|
|
401
|
+
end
|
|
402
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: avro-salsify-fork
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.9.0.
|
|
4
|
+
version: 1.9.0.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Apache Software Foundation / Salsify Engineering
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2017-01-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: multi_json
|
|
@@ -43,6 +43,7 @@ extra_rdoc_files:
|
|
|
43
43
|
- lib/avro/schema.rb
|
|
44
44
|
- lib/avro/schema_compatibility.rb
|
|
45
45
|
- lib/avro/schema_normalization.rb
|
|
46
|
+
- lib/avro/schema_validator.rb
|
|
46
47
|
files:
|
|
47
48
|
- CHANGELOG
|
|
48
49
|
- LICENSE
|
|
@@ -61,6 +62,7 @@ files:
|
|
|
61
62
|
- lib/avro/schema.rb
|
|
62
63
|
- lib/avro/schema_compatibility.rb
|
|
63
64
|
- lib/avro/schema_normalization.rb
|
|
65
|
+
- lib/avro/schema_validator.rb
|
|
64
66
|
- test/case_finder.rb
|
|
65
67
|
- test/random_data.rb
|
|
66
68
|
- test/sample_ipc_client.rb
|
|
@@ -76,6 +78,7 @@ files:
|
|
|
76
78
|
- test/test_schema.rb
|
|
77
79
|
- test/test_schema_compatibility.rb
|
|
78
80
|
- test/test_schema_normalization.rb
|
|
81
|
+
- test/test_schema_validator.rb
|
|
79
82
|
- test/test_socket_transport.rb
|
|
80
83
|
- test/tool.rb
|
|
81
84
|
homepage: https://github.com/salsify/avro
|
|
@@ -101,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
101
104
|
version: '1.2'
|
|
102
105
|
requirements: []
|
|
103
106
|
rubyforge_project: avro-salsify-fork
|
|
104
|
-
rubygems_version: 2.6.
|
|
107
|
+
rubygems_version: 2.6.8
|
|
105
108
|
signing_key:
|
|
106
109
|
specification_version: 4
|
|
107
110
|
summary: Apache Avro for Ruby with logical types patch
|
|
@@ -115,4 +118,5 @@ test_files:
|
|
|
115
118
|
- test/test_schema.rb
|
|
116
119
|
- test/test_schema_compatibility.rb
|
|
117
120
|
- test/test_schema_normalization.rb
|
|
121
|
+
- test/test_schema_validator.rb
|
|
118
122
|
- test/test_socket_transport.rb
|