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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/ext/google/protobuf_c/Rakefile +3 -0
  3. data/ext/google/protobuf_c/convert.c +153 -166
  4. data/ext/google/protobuf_c/convert.h +15 -37
  5. data/ext/google/protobuf_c/defs.c +867 -251
  6. data/ext/google/protobuf_c/defs.h +22 -47
  7. data/ext/google/protobuf_c/extconf.rb +25 -5
  8. data/ext/google/protobuf_c/glue.c +135 -0
  9. data/ext/google/protobuf_c/map.c +182 -145
  10. data/ext/google/protobuf_c/map.h +16 -35
  11. data/ext/google/protobuf_c/message.c +534 -437
  12. data/ext/google/protobuf_c/message.h +30 -49
  13. data/ext/google/protobuf_c/protobuf.c +125 -238
  14. data/ext/google/protobuf_c/protobuf.h +40 -49
  15. data/ext/google/protobuf_c/repeated_field.c +152 -120
  16. data/ext/google/protobuf_c/repeated_field.h +16 -34
  17. data/ext/google/protobuf_c/ruby-upb.c +15827 -7228
  18. data/ext/google/protobuf_c/ruby-upb.h +15075 -3866
  19. data/ext/google/protobuf_c/shared_convert.c +69 -0
  20. data/ext/google/protobuf_c/shared_convert.h +26 -0
  21. data/ext/google/protobuf_c/shared_message.c +37 -0
  22. data/ext/google/protobuf_c/shared_message.h +21 -0
  23. data/ext/google/protobuf_c/third_party/utf8_range/LICENSE +22 -0
  24. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c +207 -0
  25. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +22 -0
  26. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range_neon.inc +117 -0
  27. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range_sse.inc +272 -0
  28. data/ext/google/protobuf_c/wrap_memcpy.c +7 -29
  29. data/lib/google/protobuf/any_pb.rb +6 -8
  30. data/lib/google/protobuf/api_pb.rb +6 -26
  31. data/lib/google/protobuf/descriptor_pb.rb +24 -225
  32. data/lib/google/protobuf/duration_pb.rb +6 -8
  33. data/lib/google/protobuf/empty_pb.rb +6 -6
  34. data/lib/google/protobuf/ffi/descriptor.rb +175 -0
  35. data/lib/google/protobuf/ffi/descriptor_pool.rb +77 -0
  36. data/lib/google/protobuf/ffi/enum_descriptor.rb +183 -0
  37. data/lib/google/protobuf/ffi/ffi.rb +214 -0
  38. data/lib/google/protobuf/ffi/field_descriptor.rb +340 -0
  39. data/lib/google/protobuf/ffi/file_descriptor.rb +59 -0
  40. data/lib/google/protobuf/ffi/internal/arena.rb +60 -0
  41. data/lib/google/protobuf/ffi/internal/convert.rb +292 -0
  42. data/lib/google/protobuf/ffi/internal/pointer_helper.rb +35 -0
  43. data/lib/google/protobuf/ffi/internal/type_safety.rb +25 -0
  44. data/lib/google/protobuf/ffi/map.rb +433 -0
  45. data/lib/google/protobuf/ffi/message.rb +783 -0
  46. data/lib/google/protobuf/ffi/method_descriptor.rb +124 -0
  47. data/lib/google/protobuf/ffi/object_cache.rb +30 -0
  48. data/lib/google/protobuf/ffi/oneof_descriptor.rb +107 -0
  49. data/lib/google/protobuf/ffi/repeated_field.rb +411 -0
  50. data/lib/google/protobuf/ffi/service_descriptor.rb +117 -0
  51. data/lib/google/protobuf/field_mask_pb.rb +6 -7
  52. data/lib/google/protobuf/internal/object_cache.rb +99 -0
  53. data/lib/google/protobuf/message_exts.rb +10 -28
  54. data/lib/google/protobuf/plugin_pb.rb +25 -0
  55. data/lib/google/protobuf/repeated_field.rb +22 -33
  56. data/lib/google/protobuf/source_context_pb.rb +6 -7
  57. data/lib/google/protobuf/struct_pb.rb +6 -23
  58. data/lib/google/protobuf/timestamp_pb.rb +6 -8
  59. data/lib/google/protobuf/type_pb.rb +6 -71
  60. data/lib/google/protobuf/well_known_types.rb +16 -40
  61. data/lib/google/protobuf/wrappers_pb.rb +6 -31
  62. data/lib/google/protobuf.rb +32 -50
  63. data/lib/google/protobuf_ffi.rb +52 -0
  64. data/lib/google/protobuf_native.rb +19 -0
  65. data/lib/google/tasks/ffi.rake +100 -0
  66. metadata +97 -20
  67. data/lib/google/protobuf/descriptor_dsl.rb +0 -458
  68. data/tests/basic.rb +0 -640
  69. data/tests/generated_code_test.rb +0 -23
  70. 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