google-protobuf 3.19.1 → 3.25.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of google-protobuf might be problematic. Click here for more details.

Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/ext/google/protobuf_c/Rakefile +3 -0
  3. data/ext/google/protobuf_c/convert.c +121 -155
  4. data/ext/google/protobuf_c/convert.h +15 -37
  5. data/ext/google/protobuf_c/defs.c +362 -243
  6. data/ext/google/protobuf_c/defs.h +22 -47
  7. data/ext/google/protobuf_c/extconf.rb +13 -5
  8. data/ext/google/protobuf_c/glue.c +56 -0
  9. data/ext/google/protobuf_c/map.c +129 -137
  10. data/ext/google/protobuf_c/map.h +13 -36
  11. data/ext/google/protobuf_c/message.c +486 -389
  12. data/ext/google/protobuf_c/message.h +32 -47
  13. data/ext/google/protobuf_c/protobuf.c +101 -228
  14. data/ext/google/protobuf_c/protobuf.h +37 -42
  15. data/ext/google/protobuf_c/repeated_field.c +110 -113
  16. data/ext/google/protobuf_c/repeated_field.h +12 -34
  17. data/ext/google/protobuf_c/ruby-upb.c +12236 -6993
  18. data/ext/google/protobuf_c/ruby-upb.h +12127 -3787
  19. data/ext/google/protobuf_c/shared_convert.c +64 -0
  20. data/ext/google/protobuf_c/shared_convert.h +26 -0
  21. data/ext/google/protobuf_c/shared_message.c +65 -0
  22. data/ext/google/protobuf_c/shared_message.h +25 -0
  23. data/ext/google/protobuf_c/third_party/utf8_range/LICENSE +22 -0
  24. data/ext/google/protobuf_c/third_party/utf8_range/naive.c +92 -0
  25. data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +157 -0
  26. data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +170 -0
  27. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +21 -0
  28. data/ext/google/protobuf_c/wrap_memcpy.c +7 -29
  29. data/lib/google/protobuf/any_pb.rb +24 -5
  30. data/lib/google/protobuf/api_pb.rb +26 -23
  31. data/lib/google/protobuf/descriptor_dsl.rb +8 -1
  32. data/lib/google/protobuf/descriptor_pb.rb +43 -225
  33. data/lib/google/protobuf/duration_pb.rb +24 -5
  34. data/lib/google/protobuf/empty_pb.rb +24 -3
  35. data/lib/google/protobuf/ffi/descriptor.rb +165 -0
  36. data/lib/google/protobuf/ffi/descriptor_pool.rb +75 -0
  37. data/lib/google/protobuf/ffi/enum_descriptor.rb +171 -0
  38. data/lib/google/protobuf/ffi/ffi.rb +213 -0
  39. data/lib/google/protobuf/ffi/field_descriptor.rb +319 -0
  40. data/lib/google/protobuf/ffi/file_descriptor.rb +59 -0
  41. data/lib/google/protobuf/ffi/internal/arena.rb +66 -0
  42. data/lib/google/protobuf/ffi/internal/convert.rb +305 -0
  43. data/lib/google/protobuf/ffi/internal/pointer_helper.rb +35 -0
  44. data/lib/google/protobuf/ffi/internal/type_safety.rb +25 -0
  45. data/lib/google/protobuf/ffi/map.rb +407 -0
  46. data/lib/google/protobuf/ffi/message.rb +662 -0
  47. data/lib/google/protobuf/ffi/object_cache.rb +30 -0
  48. data/lib/google/protobuf/ffi/oneof_descriptor.rb +95 -0
  49. data/lib/google/protobuf/ffi/repeated_field.rb +383 -0
  50. data/lib/google/protobuf/field_mask_pb.rb +24 -4
  51. data/lib/google/protobuf/message_exts.rb +10 -28
  52. data/lib/google/protobuf/object_cache.rb +97 -0
  53. data/lib/google/protobuf/plugin_pb.rb +47 -0
  54. data/lib/google/protobuf/repeated_field.rb +18 -28
  55. data/lib/google/protobuf/source_context_pb.rb +24 -4
  56. data/lib/google/protobuf/struct_pb.rb +24 -20
  57. data/lib/google/protobuf/timestamp_pb.rb +24 -5
  58. data/lib/google/protobuf/type_pb.rb +26 -68
  59. data/lib/google/protobuf/well_known_types.rb +16 -40
  60. data/lib/google/protobuf/wrappers_pb.rb +24 -28
  61. data/lib/google/protobuf.rb +32 -50
  62. data/lib/google/protobuf_ffi.rb +50 -0
  63. data/lib/google/protobuf_native.rb +20 -0
  64. data/lib/google/tasks/ffi.rake +102 -0
  65. metadata +82 -20
  66. data/tests/basic.rb +0 -640
  67. data/tests/generated_code_test.rb +0 -23
  68. 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