google-protobuf 3.19.4 → 3.25.0

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