google-protobuf 3.19.1 → 4.30.2
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/ext/google/protobuf_c/Rakefile +3 -0
- data/ext/google/protobuf_c/convert.c +153 -166
- data/ext/google/protobuf_c/convert.h +15 -37
- data/ext/google/protobuf_c/defs.c +867 -251
- data/ext/google/protobuf_c/defs.h +22 -47
- data/ext/google/protobuf_c/extconf.rb +25 -5
- data/ext/google/protobuf_c/glue.c +135 -0
- data/ext/google/protobuf_c/map.c +182 -145
- data/ext/google/protobuf_c/map.h +16 -35
- data/ext/google/protobuf_c/message.c +534 -437
- data/ext/google/protobuf_c/message.h +30 -49
- data/ext/google/protobuf_c/protobuf.c +125 -238
- data/ext/google/protobuf_c/protobuf.h +40 -49
- data/ext/google/protobuf_c/repeated_field.c +152 -120
- data/ext/google/protobuf_c/repeated_field.h +16 -34
- data/ext/google/protobuf_c/ruby-upb.c +15827 -7228
- data/ext/google/protobuf_c/ruby-upb.h +15075 -3866
- data/ext/google/protobuf_c/shared_convert.c +69 -0
- data/ext/google/protobuf_c/shared_convert.h +26 -0
- data/ext/google/protobuf_c/shared_message.c +37 -0
- data/ext/google/protobuf_c/shared_message.h +21 -0
- data/ext/google/protobuf_c/third_party/utf8_range/LICENSE +22 -0
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c +207 -0
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +22 -0
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range_neon.inc +117 -0
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range_sse.inc +272 -0
- data/ext/google/protobuf_c/wrap_memcpy.c +7 -29
- data/lib/google/protobuf/any_pb.rb +6 -8
- data/lib/google/protobuf/api_pb.rb +6 -26
- data/lib/google/protobuf/descriptor_pb.rb +24 -225
- data/lib/google/protobuf/duration_pb.rb +6 -8
- data/lib/google/protobuf/empty_pb.rb +6 -6
- data/lib/google/protobuf/ffi/descriptor.rb +175 -0
- data/lib/google/protobuf/ffi/descriptor_pool.rb +77 -0
- data/lib/google/protobuf/ffi/enum_descriptor.rb +183 -0
- data/lib/google/protobuf/ffi/ffi.rb +214 -0
- data/lib/google/protobuf/ffi/field_descriptor.rb +340 -0
- data/lib/google/protobuf/ffi/file_descriptor.rb +59 -0
- data/lib/google/protobuf/ffi/internal/arena.rb +60 -0
- data/lib/google/protobuf/ffi/internal/convert.rb +292 -0
- data/lib/google/protobuf/ffi/internal/pointer_helper.rb +35 -0
- data/lib/google/protobuf/ffi/internal/type_safety.rb +25 -0
- data/lib/google/protobuf/ffi/map.rb +433 -0
- data/lib/google/protobuf/ffi/message.rb +783 -0
- data/lib/google/protobuf/ffi/method_descriptor.rb +124 -0
- data/lib/google/protobuf/ffi/object_cache.rb +30 -0
- data/lib/google/protobuf/ffi/oneof_descriptor.rb +107 -0
- data/lib/google/protobuf/ffi/repeated_field.rb +411 -0
- data/lib/google/protobuf/ffi/service_descriptor.rb +117 -0
- data/lib/google/protobuf/field_mask_pb.rb +6 -7
- data/lib/google/protobuf/internal/object_cache.rb +99 -0
- data/lib/google/protobuf/message_exts.rb +10 -28
- data/lib/google/protobuf/plugin_pb.rb +25 -0
- data/lib/google/protobuf/repeated_field.rb +22 -33
- data/lib/google/protobuf/source_context_pb.rb +6 -7
- data/lib/google/protobuf/struct_pb.rb +6 -23
- data/lib/google/protobuf/timestamp_pb.rb +6 -8
- data/lib/google/protobuf/type_pb.rb +6 -71
- data/lib/google/protobuf/well_known_types.rb +16 -40
- data/lib/google/protobuf/wrappers_pb.rb +6 -31
- data/lib/google/protobuf.rb +32 -50
- data/lib/google/protobuf_ffi.rb +52 -0
- data/lib/google/protobuf_native.rb +19 -0
- data/lib/google/tasks/ffi.rake +100 -0
- metadata +97 -20
- data/lib/google/protobuf/descriptor_dsl.rb +0 -458
- data/tests/basic.rb +0 -640
- data/tests/generated_code_test.rb +0 -23
- data/tests/stress.rb +0 -38
data/tests/basic.rb
DELETED
@@ -1,640 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
|
3
|
-
# basic_test_pb.rb is in the same directory as this test.
|
4
|
-
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))
|
5
|
-
|
6
|
-
require 'basic_test_pb'
|
7
|
-
require 'common_tests'
|
8
|
-
require 'google/protobuf'
|
9
|
-
require 'json'
|
10
|
-
require 'test/unit'
|
11
|
-
|
12
|
-
# ------------- generated code --------------
|
13
|
-
|
14
|
-
module BasicTest
|
15
|
-
pool = Google::Protobuf::DescriptorPool.new
|
16
|
-
pool.build do
|
17
|
-
add_message "BadFieldNames" do
|
18
|
-
optional :dup, :int32, 1
|
19
|
-
optional :class, :int32, 2
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
BadFieldNames = pool.lookup("BadFieldNames").msgclass
|
24
|
-
|
25
|
-
# ------------ test cases ---------------
|
26
|
-
|
27
|
-
class MessageContainerTest < Test::Unit::TestCase
|
28
|
-
# Required by CommonTests module to resolve proto3 proto classes used in tests.
|
29
|
-
def proto_module
|
30
|
-
::BasicTest
|
31
|
-
end
|
32
|
-
include CommonTests
|
33
|
-
|
34
|
-
def test_issue_8311_crash
|
35
|
-
Google::Protobuf::DescriptorPool.generated_pool.build do
|
36
|
-
add_file("inner.proto", :syntax => :proto3) do
|
37
|
-
add_message "Inner" do
|
38
|
-
# Removing either of these fixes the segfault.
|
39
|
-
optional :foo, :string, 1
|
40
|
-
optional :bar, :string, 2
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
Google::Protobuf::DescriptorPool.generated_pool.build do
|
46
|
-
add_file("outer.proto", :syntax => :proto3) do
|
47
|
-
add_message "Outer" do
|
48
|
-
repeated :inners, :message, 1, "Inner"
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
outer = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("Outer").msgclass
|
54
|
-
|
55
|
-
outer.new(
|
56
|
-
inners: []
|
57
|
-
)['inners'].to_s
|
58
|
-
|
59
|
-
assert_raise Google::Protobuf::TypeError do
|
60
|
-
outer.new(
|
61
|
-
inners: [nil]
|
62
|
-
).to_s
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def test_issue_8559_crash
|
67
|
-
msg = TestMessage.new
|
68
|
-
msg.repeated_int32 = ::Google::Protobuf::RepeatedField.new(:int32, [1, 2, 3])
|
69
|
-
# TODO: Remove the platform check once https://github.com/jruby/jruby/issues/6818 is released in JRuby 9.3.0.0
|
70
|
-
GC.start(full_mark: true, immediate_sweep: true) unless RUBY_PLATFORM == "java"
|
71
|
-
TestMessage.encode(msg)
|
72
|
-
end
|
73
|
-
|
74
|
-
def test_has_field
|
75
|
-
m = TestSingularFields.new
|
76
|
-
assert !m.has_singular_msg?
|
77
|
-
m.singular_msg = TestMessage2.new
|
78
|
-
assert m.has_singular_msg?
|
79
|
-
assert TestSingularFields.descriptor.lookup('singular_msg').has?(m)
|
80
|
-
|
81
|
-
m = OneofMessage.new
|
82
|
-
assert !m.has_my_oneof?
|
83
|
-
m.a = "foo"
|
84
|
-
assert m.has_my_oneof?
|
85
|
-
assert_raise NoMethodError do
|
86
|
-
m.has_a?
|
87
|
-
end
|
88
|
-
assert_true OneofMessage.descriptor.lookup('a').has?(m)
|
89
|
-
|
90
|
-
m = TestSingularFields.new
|
91
|
-
assert_raise NoMethodError do
|
92
|
-
m.has_singular_int32?
|
93
|
-
end
|
94
|
-
assert_raise ArgumentError do
|
95
|
-
TestSingularFields.descriptor.lookup('singular_int32').has?(m)
|
96
|
-
end
|
97
|
-
|
98
|
-
assert_raise NoMethodError do
|
99
|
-
m.has_singular_string?
|
100
|
-
end
|
101
|
-
assert_raise ArgumentError do
|
102
|
-
TestSingularFields.descriptor.lookup('singular_string').has?(m)
|
103
|
-
end
|
104
|
-
|
105
|
-
assert_raise NoMethodError do
|
106
|
-
m.has_singular_bool?
|
107
|
-
end
|
108
|
-
assert_raise ArgumentError do
|
109
|
-
TestSingularFields.descriptor.lookup('singular_bool').has?(m)
|
110
|
-
end
|
111
|
-
|
112
|
-
m = TestMessage.new
|
113
|
-
assert_raise NoMethodError do
|
114
|
-
m.has_repeated_msg?
|
115
|
-
end
|
116
|
-
assert_raise ArgumentError do
|
117
|
-
TestMessage.descriptor.lookup('repeated_msg').has?(m)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
def test_no_presence
|
122
|
-
m = TestSingularFields.new
|
123
|
-
|
124
|
-
# Explicitly setting to zero does not cause anything to be serialized.
|
125
|
-
m.singular_int32 = 0
|
126
|
-
assert_equal "", TestSingularFields.encode(m)
|
127
|
-
|
128
|
-
# Explicitly setting to a non-zero value *does* cause serialization.
|
129
|
-
m.singular_int32 = 1
|
130
|
-
assert_not_equal "", TestSingularFields.encode(m)
|
131
|
-
|
132
|
-
m.singular_int32 = 0
|
133
|
-
assert_equal "", TestSingularFields.encode(m)
|
134
|
-
end
|
135
|
-
|
136
|
-
def test_set_clear_defaults
|
137
|
-
m = TestSingularFields.new
|
138
|
-
|
139
|
-
m.singular_int32 = -42
|
140
|
-
assert_equal -42, m.singular_int32
|
141
|
-
m.clear_singular_int32
|
142
|
-
assert_equal 0, m.singular_int32
|
143
|
-
|
144
|
-
m.singular_int32 = 50
|
145
|
-
assert_equal 50, m.singular_int32
|
146
|
-
TestSingularFields.descriptor.lookup('singular_int32').clear(m)
|
147
|
-
assert_equal 0, m.singular_int32
|
148
|
-
|
149
|
-
m.singular_string = "foo bar"
|
150
|
-
assert_equal "foo bar", m.singular_string
|
151
|
-
m.clear_singular_string
|
152
|
-
assert_equal "", m.singular_string
|
153
|
-
|
154
|
-
m.singular_string = "foo"
|
155
|
-
assert_equal "foo", m.singular_string
|
156
|
-
TestSingularFields.descriptor.lookup('singular_string').clear(m)
|
157
|
-
assert_equal "", m.singular_string
|
158
|
-
|
159
|
-
m.singular_msg = TestMessage2.new(:foo => 42)
|
160
|
-
assert_equal TestMessage2.new(:foo => 42), m.singular_msg
|
161
|
-
assert m.has_singular_msg?
|
162
|
-
m.clear_singular_msg
|
163
|
-
assert_equal nil, m.singular_msg
|
164
|
-
assert !m.has_singular_msg?
|
165
|
-
|
166
|
-
m.singular_msg = TestMessage2.new(:foo => 42)
|
167
|
-
assert_equal TestMessage2.new(:foo => 42), m.singular_msg
|
168
|
-
TestSingularFields.descriptor.lookup('singular_msg').clear(m)
|
169
|
-
assert_equal nil, m.singular_msg
|
170
|
-
end
|
171
|
-
|
172
|
-
def test_import_proto2
|
173
|
-
m = TestMessage.new
|
174
|
-
assert !m.has_optional_proto2_submessage?
|
175
|
-
m.optional_proto2_submessage = ::FooBar::Proto2::TestImportedMessage.new
|
176
|
-
assert m.has_optional_proto2_submessage?
|
177
|
-
assert TestMessage.descriptor.lookup('optional_proto2_submessage').has?(m)
|
178
|
-
|
179
|
-
m.clear_optional_proto2_submessage
|
180
|
-
assert !m.has_optional_proto2_submessage?
|
181
|
-
end
|
182
|
-
|
183
|
-
def test_clear_repeated_fields
|
184
|
-
m = TestMessage.new
|
185
|
-
|
186
|
-
m.repeated_int32.push(1)
|
187
|
-
assert_equal [1], m.repeated_int32
|
188
|
-
m.clear_repeated_int32
|
189
|
-
assert_equal [], m.repeated_int32
|
190
|
-
|
191
|
-
m.repeated_int32.push(1)
|
192
|
-
assert_equal [1], m.repeated_int32
|
193
|
-
TestMessage.descriptor.lookup('repeated_int32').clear(m)
|
194
|
-
assert_equal [], m.repeated_int32
|
195
|
-
|
196
|
-
m = OneofMessage.new
|
197
|
-
m.a = "foo"
|
198
|
-
assert_equal "foo", m.a
|
199
|
-
assert m.has_my_oneof?
|
200
|
-
assert_equal :a, m.my_oneof
|
201
|
-
m.clear_a
|
202
|
-
assert !m.has_my_oneof?
|
203
|
-
|
204
|
-
m.a = "foobar"
|
205
|
-
assert m.has_my_oneof?
|
206
|
-
m.clear_my_oneof
|
207
|
-
assert !m.has_my_oneof?
|
208
|
-
|
209
|
-
m.a = "bar"
|
210
|
-
assert_equal "bar", m.a
|
211
|
-
assert m.has_my_oneof?
|
212
|
-
OneofMessage.descriptor.lookup('a').clear(m)
|
213
|
-
assert !m.has_my_oneof?
|
214
|
-
end
|
215
|
-
|
216
|
-
def test_initialization_map_errors
|
217
|
-
e = assert_raise ArgumentError do
|
218
|
-
TestMessage.new(:hello => "world")
|
219
|
-
end
|
220
|
-
assert_match(/hello/, e.message)
|
221
|
-
|
222
|
-
e = assert_raise ArgumentError do
|
223
|
-
MapMessage.new(:map_string_int32 => "hello")
|
224
|
-
end
|
225
|
-
assert_equal e.message, "Expected Hash object as initializer value for map field 'map_string_int32' (given String)."
|
226
|
-
|
227
|
-
e = assert_raise ArgumentError do
|
228
|
-
TestMessage.new(:repeated_uint32 => "hello")
|
229
|
-
end
|
230
|
-
assert_equal e.message, "Expected array as initializer value for repeated field 'repeated_uint32' (given String)."
|
231
|
-
end
|
232
|
-
|
233
|
-
def test_map_field
|
234
|
-
m = MapMessage.new
|
235
|
-
assert m.map_string_int32 == {}
|
236
|
-
assert m.map_string_msg == {}
|
237
|
-
|
238
|
-
m = MapMessage.new(
|
239
|
-
:map_string_int32 => {"a" => 1, "b" => 2},
|
240
|
-
:map_string_msg => {"a" => TestMessage2.new(:foo => 1),
|
241
|
-
"b" => TestMessage2.new(:foo => 2)},
|
242
|
-
:map_string_enum => {"a" => :A, "b" => :B})
|
243
|
-
assert m.map_string_int32.keys.sort == ["a", "b"]
|
244
|
-
assert m.map_string_int32["a"] == 1
|
245
|
-
assert m.map_string_msg["b"].foo == 2
|
246
|
-
assert m.map_string_enum["a"] == :A
|
247
|
-
|
248
|
-
m.map_string_int32["c"] = 3
|
249
|
-
assert m.map_string_int32["c"] == 3
|
250
|
-
m.map_string_msg["c"] = TestMessage2.new(:foo => 3)
|
251
|
-
assert m.map_string_msg["c"] == TestMessage2.new(:foo => 3)
|
252
|
-
m.map_string_msg.delete("b")
|
253
|
-
m.map_string_msg.delete("c")
|
254
|
-
assert m.map_string_msg == { "a" => TestMessage2.new(:foo => 1) }
|
255
|
-
|
256
|
-
assert_raise Google::Protobuf::TypeError do
|
257
|
-
m.map_string_msg["e"] = TestMessage.new # wrong value type
|
258
|
-
end
|
259
|
-
# ensure nothing was added by the above
|
260
|
-
assert m.map_string_msg == { "a" => TestMessage2.new(:foo => 1) }
|
261
|
-
|
262
|
-
m.map_string_int32 = Google::Protobuf::Map.new(:string, :int32)
|
263
|
-
assert_raise Google::Protobuf::TypeError do
|
264
|
-
m.map_string_int32 = Google::Protobuf::Map.new(:string, :int64)
|
265
|
-
end
|
266
|
-
assert_raise Google::Protobuf::TypeError do
|
267
|
-
m.map_string_int32 = {}
|
268
|
-
end
|
269
|
-
|
270
|
-
assert_raise Google::Protobuf::TypeError do
|
271
|
-
m = MapMessage.new(:map_string_int32 => { 1 => "I am not a number" })
|
272
|
-
end
|
273
|
-
end
|
274
|
-
|
275
|
-
def test_map_field_with_symbol
|
276
|
-
m = MapMessage.new
|
277
|
-
assert m.map_string_int32 == {}
|
278
|
-
assert m.map_string_msg == {}
|
279
|
-
|
280
|
-
m = MapMessage.new(
|
281
|
-
:map_string_int32 => {a: 1, "b" => 2},
|
282
|
-
:map_string_msg => {a: TestMessage2.new(:foo => 1),
|
283
|
-
b: TestMessage2.new(:foo => 10)})
|
284
|
-
assert_equal 1, m.map_string_int32[:a]
|
285
|
-
assert_equal 2, m.map_string_int32[:b]
|
286
|
-
assert_equal 10, m.map_string_msg[:b].foo
|
287
|
-
end
|
288
|
-
|
289
|
-
def test_map_inspect
|
290
|
-
m = MapMessage.new(
|
291
|
-
:map_string_int32 => {"a" => 1, "b" => 2},
|
292
|
-
:map_string_msg => {"a" => TestMessage2.new(:foo => 1),
|
293
|
-
"b" => TestMessage2.new(:foo => 2)},
|
294
|
-
:map_string_enum => {"a" => :A, "b" => :B})
|
295
|
-
|
296
|
-
# JRuby doesn't keep consistent ordering so check for either version
|
297
|
-
expected_a = "<BasicTest::MapMessage: map_string_int32: {\"b\"=>2, \"a\"=>1}, map_string_msg: {\"b\"=><BasicTest::TestMessage2: foo: 2>, \"a\"=><BasicTest::TestMessage2: foo: 1>}, map_string_enum: {\"b\"=>:B, \"a\"=>:A}>"
|
298
|
-
expected_b = "<BasicTest::MapMessage: map_string_int32: {\"a\"=>1, \"b\"=>2}, map_string_msg: {\"a\"=><BasicTest::TestMessage2: foo: 1>, \"b\"=><BasicTest::TestMessage2: foo: 2>}, map_string_enum: {\"a\"=>:A, \"b\"=>:B}>"
|
299
|
-
inspect_result = m.inspect
|
300
|
-
assert expected_a == inspect_result || expected_b == inspect_result, "Incorrect inspect result: #{inspect_result}"
|
301
|
-
end
|
302
|
-
|
303
|
-
def test_map_corruption
|
304
|
-
# This pattern led to a crash in a previous version of upb/protobuf.
|
305
|
-
m = MapMessage.new(map_string_int32: { "aaa" => 1 })
|
306
|
-
m.map_string_int32['podid'] = 2
|
307
|
-
m.map_string_int32['aaa'] = 3
|
308
|
-
end
|
309
|
-
|
310
|
-
def test_map_wrappers
|
311
|
-
run_asserts = ->(m) {
|
312
|
-
assert_equal 2.0, m.map_double[0].value
|
313
|
-
assert_equal 4.0, m.map_float[0].value
|
314
|
-
assert_equal 3, m.map_int32[0].value
|
315
|
-
assert_equal 4, m.map_int64[0].value
|
316
|
-
assert_equal 5, m.map_uint32[0].value
|
317
|
-
assert_equal 6, m.map_uint64[0].value
|
318
|
-
assert_equal true, m.map_bool[0].value
|
319
|
-
assert_equal 'str', m.map_string[0].value
|
320
|
-
assert_equal 'fun', m.map_bytes[0].value
|
321
|
-
}
|
322
|
-
|
323
|
-
m = proto_module::Wrapper.new(
|
324
|
-
map_double: {0 => Google::Protobuf::DoubleValue.new(value: 2.0)},
|
325
|
-
map_float: {0 => Google::Protobuf::FloatValue.new(value: 4.0)},
|
326
|
-
map_int32: {0 => Google::Protobuf::Int32Value.new(value: 3)},
|
327
|
-
map_int64: {0 => Google::Protobuf::Int64Value.new(value: 4)},
|
328
|
-
map_uint32: {0 => Google::Protobuf::UInt32Value.new(value: 5)},
|
329
|
-
map_uint64: {0 => Google::Protobuf::UInt64Value.new(value: 6)},
|
330
|
-
map_bool: {0 => Google::Protobuf::BoolValue.new(value: true)},
|
331
|
-
map_string: {0 => Google::Protobuf::StringValue.new(value: 'str')},
|
332
|
-
map_bytes: {0 => Google::Protobuf::BytesValue.new(value: 'fun')},
|
333
|
-
)
|
334
|
-
|
335
|
-
run_asserts.call(m)
|
336
|
-
serialized = proto_module::Wrapper::encode(m)
|
337
|
-
m2 = proto_module::Wrapper::decode(serialized)
|
338
|
-
run_asserts.call(m2)
|
339
|
-
|
340
|
-
# Test the case where we are serializing directly from the parsed form
|
341
|
-
# (before anything lazy is materialized).
|
342
|
-
m3 = proto_module::Wrapper::decode(serialized)
|
343
|
-
serialized2 = proto_module::Wrapper::encode(m3)
|
344
|
-
m4 = proto_module::Wrapper::decode(serialized2)
|
345
|
-
run_asserts.call(m4)
|
346
|
-
|
347
|
-
# Test that the lazy form compares equal to the expanded form.
|
348
|
-
m5 = proto_module::Wrapper::decode(serialized2)
|
349
|
-
assert_equal m5, m
|
350
|
-
end
|
351
|
-
|
352
|
-
def test_map_wrappers_with_default_values
|
353
|
-
run_asserts = ->(m) {
|
354
|
-
assert_equal 0.0, m.map_double[0].value
|
355
|
-
assert_equal 0.0, m.map_float[0].value
|
356
|
-
assert_equal 0, m.map_int32[0].value
|
357
|
-
assert_equal 0, m.map_int64[0].value
|
358
|
-
assert_equal 0, m.map_uint32[0].value
|
359
|
-
assert_equal 0, m.map_uint64[0].value
|
360
|
-
assert_equal false, m.map_bool[0].value
|
361
|
-
assert_equal '', m.map_string[0].value
|
362
|
-
assert_equal '', m.map_bytes[0].value
|
363
|
-
}
|
364
|
-
|
365
|
-
m = proto_module::Wrapper.new(
|
366
|
-
map_double: {0 => Google::Protobuf::DoubleValue.new(value: 0.0)},
|
367
|
-
map_float: {0 => Google::Protobuf::FloatValue.new(value: 0.0)},
|
368
|
-
map_int32: {0 => Google::Protobuf::Int32Value.new(value: 0)},
|
369
|
-
map_int64: {0 => Google::Protobuf::Int64Value.new(value: 0)},
|
370
|
-
map_uint32: {0 => Google::Protobuf::UInt32Value.new(value: 0)},
|
371
|
-
map_uint64: {0 => Google::Protobuf::UInt64Value.new(value: 0)},
|
372
|
-
map_bool: {0 => Google::Protobuf::BoolValue.new(value: false)},
|
373
|
-
map_string: {0 => Google::Protobuf::StringValue.new(value: '')},
|
374
|
-
map_bytes: {0 => Google::Protobuf::BytesValue.new(value: '')},
|
375
|
-
)
|
376
|
-
|
377
|
-
run_asserts.call(m)
|
378
|
-
serialized = proto_module::Wrapper::encode(m)
|
379
|
-
m2 = proto_module::Wrapper::decode(serialized)
|
380
|
-
run_asserts.call(m2)
|
381
|
-
|
382
|
-
# Test the case where we are serializing directly from the parsed form
|
383
|
-
# (before anything lazy is materialized).
|
384
|
-
m3 = proto_module::Wrapper::decode(serialized)
|
385
|
-
serialized2 = proto_module::Wrapper::encode(m3)
|
386
|
-
m4 = proto_module::Wrapper::decode(serialized2)
|
387
|
-
run_asserts.call(m4)
|
388
|
-
|
389
|
-
# Test that the lazy form compares equal to the expanded form.
|
390
|
-
m5 = proto_module::Wrapper::decode(serialized2)
|
391
|
-
assert_equal m5, m
|
392
|
-
end
|
393
|
-
|
394
|
-
def test_map_wrappers_with_no_value
|
395
|
-
run_asserts = ->(m) {
|
396
|
-
assert_equal 0.0, m.map_double[0].value
|
397
|
-
assert_equal 0.0, m.map_float[0].value
|
398
|
-
assert_equal 0, m.map_int32[0].value
|
399
|
-
assert_equal 0, m.map_int64[0].value
|
400
|
-
assert_equal 0, m.map_uint32[0].value
|
401
|
-
assert_equal 0, m.map_uint64[0].value
|
402
|
-
assert_equal false, m.map_bool[0].value
|
403
|
-
assert_equal '', m.map_string[0].value
|
404
|
-
assert_equal '', m.map_bytes[0].value
|
405
|
-
}
|
406
|
-
|
407
|
-
m = proto_module::Wrapper.new(
|
408
|
-
map_double: {0 => Google::Protobuf::DoubleValue.new()},
|
409
|
-
map_float: {0 => Google::Protobuf::FloatValue.new()},
|
410
|
-
map_int32: {0 => Google::Protobuf::Int32Value.new()},
|
411
|
-
map_int64: {0 => Google::Protobuf::Int64Value.new()},
|
412
|
-
map_uint32: {0 => Google::Protobuf::UInt32Value.new()},
|
413
|
-
map_uint64: {0 => Google::Protobuf::UInt64Value.new()},
|
414
|
-
map_bool: {0 => Google::Protobuf::BoolValue.new()},
|
415
|
-
map_string: {0 => Google::Protobuf::StringValue.new()},
|
416
|
-
map_bytes: {0 => Google::Protobuf::BytesValue.new()},
|
417
|
-
)
|
418
|
-
run_asserts.call(m)
|
419
|
-
|
420
|
-
serialized = proto_module::Wrapper::encode(m)
|
421
|
-
m2 = proto_module::Wrapper::decode(serialized)
|
422
|
-
run_asserts.call(m2)
|
423
|
-
|
424
|
-
# Test the case where we are serializing directly from the parsed form
|
425
|
-
# (before anything lazy is materialized).
|
426
|
-
m3 = proto_module::Wrapper::decode(serialized)
|
427
|
-
serialized2 = proto_module::Wrapper::encode(m3)
|
428
|
-
m4 = proto_module::Wrapper::decode(serialized2)
|
429
|
-
run_asserts.call(m4)
|
430
|
-
end
|
431
|
-
|
432
|
-
def test_concurrent_decoding
|
433
|
-
o = Outer.new
|
434
|
-
o.items[0] = Inner.new
|
435
|
-
raw = Outer.encode(o)
|
436
|
-
|
437
|
-
thds = 2.times.map do
|
438
|
-
Thread.new do
|
439
|
-
100000.times do
|
440
|
-
assert_equal o, Outer.decode(raw)
|
441
|
-
end
|
442
|
-
end
|
443
|
-
end
|
444
|
-
thds.map(&:join)
|
445
|
-
end
|
446
|
-
|
447
|
-
def test_map_encode_decode
|
448
|
-
m = MapMessage.new(
|
449
|
-
:map_string_int32 => {"a" => 1, "b" => 2},
|
450
|
-
:map_string_msg => {"a" => TestMessage2.new(:foo => 1),
|
451
|
-
"b" => TestMessage2.new(:foo => 2)},
|
452
|
-
:map_string_enum => {"a" => :A, "b" => :B})
|
453
|
-
m2 = MapMessage.decode(MapMessage.encode(m))
|
454
|
-
assert m == m2
|
455
|
-
|
456
|
-
m3 = MapMessageWireEquiv.decode(MapMessage.encode(m))
|
457
|
-
assert m3.map_string_int32.length == 2
|
458
|
-
|
459
|
-
kv = {}
|
460
|
-
m3.map_string_int32.map { |msg| kv[msg.key] = msg.value }
|
461
|
-
assert kv == {"a" => 1, "b" => 2}
|
462
|
-
|
463
|
-
kv = {}
|
464
|
-
m3.map_string_msg.map { |msg| kv[msg.key] = msg.value }
|
465
|
-
assert kv == {"a" => TestMessage2.new(:foo => 1),
|
466
|
-
"b" => TestMessage2.new(:foo => 2)}
|
467
|
-
end
|
468
|
-
|
469
|
-
def test_protobuf_decode_json_ignore_unknown_fields
|
470
|
-
m = TestMessage.decode_json({
|
471
|
-
optional_string: "foo",
|
472
|
-
not_in_message: "some_value"
|
473
|
-
}.to_json, { ignore_unknown_fields: true })
|
474
|
-
|
475
|
-
assert_equal m.optional_string, "foo"
|
476
|
-
e = assert_raise Google::Protobuf::ParseError do
|
477
|
-
TestMessage.decode_json({ not_in_message: "some_value" }.to_json)
|
478
|
-
end
|
479
|
-
assert_match(/No such field: not_in_message/, e.message)
|
480
|
-
end
|
481
|
-
|
482
|
-
#def test_json_quoted_string
|
483
|
-
# m = TestMessage.decode_json(%q(
|
484
|
-
# "optionalInt64": "1",,
|
485
|
-
# }))
|
486
|
-
# puts(m)
|
487
|
-
# assert_equal 1, m.optional_int32
|
488
|
-
#end
|
489
|
-
|
490
|
-
def test_to_h
|
491
|
-
m = TestMessage.new(:optional_bool => true, :optional_double => -10.100001, :optional_string => 'foo', :repeated_string => ['bar1', 'bar2'], :repeated_msg => [TestMessage2.new(:foo => 100)])
|
492
|
-
expected_result = {
|
493
|
-
:optional_bool=>true,
|
494
|
-
:optional_bytes=>"",
|
495
|
-
:optional_double=>-10.100001,
|
496
|
-
:optional_enum=>:Default,
|
497
|
-
:optional_float=>0.0,
|
498
|
-
:optional_int32=>0,
|
499
|
-
:optional_int64=>0,
|
500
|
-
:optional_msg=>nil,
|
501
|
-
:optional_msg2=>nil,
|
502
|
-
:optional_proto2_submessage=>nil,
|
503
|
-
:optional_string=>"foo",
|
504
|
-
:optional_uint32=>0,
|
505
|
-
:optional_uint64=>0,
|
506
|
-
:repeated_bool=>[],
|
507
|
-
:repeated_bytes=>[],
|
508
|
-
:repeated_double=>[],
|
509
|
-
:repeated_enum=>[],
|
510
|
-
:repeated_float=>[],
|
511
|
-
:repeated_int32=>[],
|
512
|
-
:repeated_int64=>[],
|
513
|
-
:repeated_msg=>[{:foo => 100}],
|
514
|
-
:repeated_string=>["bar1", "bar2"],
|
515
|
-
:repeated_uint32=>[],
|
516
|
-
:repeated_uint64=>[]
|
517
|
-
}
|
518
|
-
assert_equal expected_result, m.to_h
|
519
|
-
|
520
|
-
m = MapMessage.new(
|
521
|
-
:map_string_int32 => {"a" => 1, "b" => 2},
|
522
|
-
:map_string_msg => {"a" => TestMessage2.new(:foo => 1),
|
523
|
-
"b" => TestMessage2.new(:foo => 2)},
|
524
|
-
:map_string_enum => {"a" => :A, "b" => :B})
|
525
|
-
expected_result = {
|
526
|
-
:map_string_int32 => {"a" => 1, "b" => 2},
|
527
|
-
:map_string_msg => {"a" => {:foo => 1}, "b" => {:foo => 2}},
|
528
|
-
:map_string_enum => {"a" => :A, "b" => :B}
|
529
|
-
}
|
530
|
-
assert_equal expected_result, m.to_h
|
531
|
-
end
|
532
|
-
|
533
|
-
|
534
|
-
def test_json_maps
|
535
|
-
# TODO: Fix JSON in JRuby version.
|
536
|
-
return if RUBY_PLATFORM == "java"
|
537
|
-
m = MapMessage.new(:map_string_int32 => {"a" => 1})
|
538
|
-
expected = {mapStringInt32: {a: 1}, mapStringMsg: {}, mapStringEnum: {}}
|
539
|
-
expected_preserve = {map_string_int32: {a: 1}, map_string_msg: {}, map_string_enum: {}}
|
540
|
-
assert_equal JSON.parse(MapMessage.encode_json(m, :emit_defaults=>true), :symbolize_names => true), expected
|
541
|
-
|
542
|
-
json = MapMessage.encode_json(m, :preserve_proto_fieldnames => true, :emit_defaults=>true)
|
543
|
-
assert_equal JSON.parse(json, :symbolize_names => true), expected_preserve
|
544
|
-
|
545
|
-
m2 = MapMessage.decode_json(MapMessage.encode_json(m))
|
546
|
-
assert_equal m, m2
|
547
|
-
end
|
548
|
-
|
549
|
-
def test_json_maps_emit_defaults_submsg
|
550
|
-
# TODO: Fix JSON in JRuby version.
|
551
|
-
return if RUBY_PLATFORM == "java"
|
552
|
-
m = MapMessage.new(:map_string_msg => {"a" => TestMessage2.new(foo: 0)})
|
553
|
-
expected = {mapStringInt32: {}, mapStringMsg: {a: {foo: 0}}, mapStringEnum: {}}
|
554
|
-
|
555
|
-
actual = MapMessage.encode_json(m, :emit_defaults => true)
|
556
|
-
|
557
|
-
assert_equal JSON.parse(actual, :symbolize_names => true), expected
|
558
|
-
end
|
559
|
-
|
560
|
-
def test_json_emit_defaults_submsg
|
561
|
-
# TODO: Fix JSON in JRuby version.
|
562
|
-
return if RUBY_PLATFORM == "java"
|
563
|
-
m = TestSingularFields.new(singular_msg: proto_module::TestMessage2.new)
|
564
|
-
|
565
|
-
expected = {
|
566
|
-
singularInt32: 0,
|
567
|
-
singularInt64: "0",
|
568
|
-
singularUint32: 0,
|
569
|
-
singularUint64: "0",
|
570
|
-
singularBool: false,
|
571
|
-
singularFloat: 0,
|
572
|
-
singularDouble: 0,
|
573
|
-
singularString: "",
|
574
|
-
singularBytes: "",
|
575
|
-
singularMsg: {},
|
576
|
-
singularEnum: "Default",
|
577
|
-
}
|
578
|
-
|
579
|
-
actual = proto_module::TestMessage.encode_json(m, :emit_defaults => true)
|
580
|
-
|
581
|
-
assert_equal expected, JSON.parse(actual, :symbolize_names => true)
|
582
|
-
end
|
583
|
-
|
584
|
-
def test_respond_to
|
585
|
-
# This test fails with JRuby 1.7.23, likely because of an old JRuby bug.
|
586
|
-
return if RUBY_PLATFORM == "java"
|
587
|
-
msg = MapMessage.new
|
588
|
-
assert msg.respond_to?(:map_string_int32)
|
589
|
-
assert !msg.respond_to?(:bacon)
|
590
|
-
end
|
591
|
-
|
592
|
-
def test_file_descriptor
|
593
|
-
file_descriptor = TestMessage.descriptor.file_descriptor
|
594
|
-
assert nil != file_descriptor
|
595
|
-
assert_equal "tests/basic_test.proto", file_descriptor.name
|
596
|
-
assert_equal :proto3, file_descriptor.syntax
|
597
|
-
|
598
|
-
file_descriptor = TestEnum.descriptor.file_descriptor
|
599
|
-
assert nil != file_descriptor
|
600
|
-
assert_equal "tests/basic_test.proto", file_descriptor.name
|
601
|
-
assert_equal :proto3, file_descriptor.syntax
|
602
|
-
end
|
603
|
-
|
604
|
-
# Ruby 2.5 changed to raise FrozenError instead of RuntimeError
|
605
|
-
FrozenErrorType = Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.5') ? RuntimeError : FrozenError
|
606
|
-
|
607
|
-
def test_map_freeze
|
608
|
-
m = proto_module::MapMessage.new
|
609
|
-
m.map_string_int32['a'] = 5
|
610
|
-
m.map_string_msg['b'] = proto_module::TestMessage2.new
|
611
|
-
|
612
|
-
m.map_string_int32.freeze
|
613
|
-
m.map_string_msg.freeze
|
614
|
-
|
615
|
-
assert m.map_string_int32.frozen?
|
616
|
-
assert m.map_string_msg.frozen?
|
617
|
-
|
618
|
-
assert_raise(FrozenErrorType) { m.map_string_int32['foo'] = 1 }
|
619
|
-
assert_raise(FrozenErrorType) { m.map_string_msg['bar'] = proto_module::TestMessage2.new }
|
620
|
-
assert_raise(FrozenErrorType) { m.map_string_int32.delete('a') }
|
621
|
-
assert_raise(FrozenErrorType) { m.map_string_int32.clear }
|
622
|
-
end
|
623
|
-
|
624
|
-
def test_map_length
|
625
|
-
m = proto_module::MapMessage.new
|
626
|
-
assert_equal 0, m.map_string_int32.length
|
627
|
-
assert_equal 0, m.map_string_msg.length
|
628
|
-
assert_equal 0, m.map_string_int32.size
|
629
|
-
assert_equal 0, m.map_string_msg.size
|
630
|
-
|
631
|
-
m.map_string_int32['a'] = 1
|
632
|
-
m.map_string_int32['b'] = 2
|
633
|
-
m.map_string_msg['a'] = proto_module::TestMessage2.new
|
634
|
-
assert_equal 2, m.map_string_int32.length
|
635
|
-
assert_equal 1, m.map_string_msg.length
|
636
|
-
assert_equal 2, m.map_string_int32.size
|
637
|
-
assert_equal 1, m.map_string_msg.size
|
638
|
-
end
|
639
|
-
end
|
640
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
|
3
|
-
# generated_code.rb is in the same directory as this test.
|
4
|
-
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))
|
5
|
-
|
6
|
-
require 'generated_code_pb'
|
7
|
-
require 'test_import_pb'
|
8
|
-
require 'test_ruby_package_pb'
|
9
|
-
require 'test/unit'
|
10
|
-
|
11
|
-
class GeneratedCodeTest < Test::Unit::TestCase
|
12
|
-
def test_generated_msg
|
13
|
-
# just test that we can instantiate the message. The purpose of this test
|
14
|
-
# is to ensure that the output of the code generator is valid Ruby and
|
15
|
-
# successfully creates message definitions and classes, not to test every
|
16
|
-
# aspect of the extension (basic.rb is for that).
|
17
|
-
A::B::C::TestMessage.new
|
18
|
-
A::B::C::TestMessage::NestedMessage.new
|
19
|
-
A::B::C::TestLowercaseNested::Lowercase.new
|
20
|
-
FooBar::TestImportedMessage.new
|
21
|
-
A::B::TestRubyPackageMessage.new
|
22
|
-
end
|
23
|
-
end
|
data/tests/stress.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
|
3
|
-
require 'google/protobuf'
|
4
|
-
require 'test/unit'
|
5
|
-
|
6
|
-
module StressTest
|
7
|
-
pool = Google::Protobuf::DescriptorPool.new
|
8
|
-
pool.build do
|
9
|
-
add_message "TestMessage" do
|
10
|
-
optional :a, :int32, 1
|
11
|
-
repeated :b, :message, 2, "M"
|
12
|
-
end
|
13
|
-
add_message "M" do
|
14
|
-
optional :foo, :string, 1
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
TestMessage = pool.lookup("TestMessage").msgclass
|
19
|
-
M = pool.lookup("M").msgclass
|
20
|
-
|
21
|
-
class StressTest < Test::Unit::TestCase
|
22
|
-
def get_msg
|
23
|
-
TestMessage.new(:a => 1000,
|
24
|
-
:b => [M.new(:foo => "hello"),
|
25
|
-
M.new(:foo => "world")])
|
26
|
-
end
|
27
|
-
def test_stress
|
28
|
-
m = get_msg
|
29
|
-
data = TestMessage.encode(m)
|
30
|
-
100_000.times do
|
31
|
-
mnew = TestMessage.decode(data)
|
32
|
-
mnew = mnew.dup
|
33
|
-
assert_equal m.inspect, mnew.inspect
|
34
|
-
assert TestMessage.encode(mnew) == data
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|