google-protobuf 3.2.0.2-java → 3.19.0.rc.2-java

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.

Potentially problematic release.


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

data/tests/basic.rb CHANGED
@@ -1,6 +1,12 @@
1
1
  #!/usr/bin/ruby
2
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'
3
8
  require 'google/protobuf'
9
+ require 'json'
4
10
  require 'test/unit'
5
11
 
6
12
  # ------------- generated code --------------
@@ -8,623 +14,220 @@ require 'test/unit'
8
14
  module BasicTest
9
15
  pool = Google::Protobuf::DescriptorPool.new
10
16
  pool.build do
11
- add_message "Foo" do
12
- optional :bar, :message, 1, "Bar"
13
- repeated :baz, :message, 2, "Baz"
14
- end
15
-
16
- add_message "Bar" do
17
- optional :msg, :string, 1
18
- end
19
-
20
- add_message "Baz" do
21
- optional :msg, :string, 1
22
- end
23
-
24
- add_message "TestMessage" do
25
- optional :optional_int32, :int32, 1
26
- optional :optional_int64, :int64, 2
27
- optional :optional_uint32, :uint32, 3
28
- optional :optional_uint64, :uint64, 4
29
- optional :optional_bool, :bool, 5
30
- optional :optional_float, :float, 6
31
- optional :optional_double, :double, 7
32
- optional :optional_string, :string, 8
33
- optional :optional_bytes, :bytes, 9
34
- optional :optional_msg, :message, 10, "TestMessage2"
35
- optional :optional_enum, :enum, 11, "TestEnum"
36
-
37
- repeated :repeated_int32, :int32, 12
38
- repeated :repeated_int64, :int64, 13
39
- repeated :repeated_uint32, :uint32, 14
40
- repeated :repeated_uint64, :uint64, 15
41
- repeated :repeated_bool, :bool, 16
42
- repeated :repeated_float, :float, 17
43
- repeated :repeated_double, :double, 18
44
- repeated :repeated_string, :string, 19
45
- repeated :repeated_bytes, :bytes, 20
46
- repeated :repeated_msg, :message, 21, "TestMessage2"
47
- repeated :repeated_enum, :enum, 22, "TestEnum"
48
- end
49
- add_message "TestMessage2" do
50
- optional :foo, :int32, 1
51
- end
52
-
53
- add_message "Recursive1" do
54
- optional :foo, :message, 1, "Recursive2"
55
- end
56
- add_message "Recursive2" do
57
- optional :foo, :message, 1, "Recursive1"
58
- end
59
-
60
- add_enum "TestEnum" do
61
- value :Default, 0
62
- value :A, 1
63
- value :B, 2
64
- value :C, 3
65
- end
66
-
67
17
  add_message "BadFieldNames" do
68
18
  optional :dup, :int32, 1
69
19
  optional :class, :int32, 2
70
- optional :"a.b", :int32, 3
71
- end
72
-
73
- add_message "MapMessage" do
74
- map :map_string_int32, :string, :int32, 1
75
- map :map_string_msg, :string, :message, 2, "TestMessage2"
76
- end
77
- add_message "MapMessageWireEquiv" do
78
- repeated :map_string_int32, :message, 1, "MapMessageWireEquiv_entry1"
79
- repeated :map_string_msg, :message, 2, "MapMessageWireEquiv_entry2"
80
- end
81
- add_message "MapMessageWireEquiv_entry1" do
82
- optional :key, :string, 1
83
- optional :value, :int32, 2
84
- end
85
- add_message "MapMessageWireEquiv_entry2" do
86
- optional :key, :string, 1
87
- optional :value, :message, 2, "TestMessage2"
88
- end
89
-
90
- add_message "OneofMessage" do
91
- oneof :my_oneof do
92
- optional :a, :string, 1
93
- optional :b, :int32, 2
94
- optional :c, :message, 3, "TestMessage2"
95
- optional :d, :enum, 4, "TestEnum"
96
- end
97
20
  end
98
21
  end
99
22
 
100
- Foo = pool.lookup("Foo").msgclass
101
- Bar = pool.lookup("Bar").msgclass
102
- Baz = pool.lookup("Baz").msgclass
103
- TestMessage = pool.lookup("TestMessage").msgclass
104
- TestMessage2 = pool.lookup("TestMessage2").msgclass
105
- Recursive1 = pool.lookup("Recursive1").msgclass
106
- Recursive2 = pool.lookup("Recursive2").msgclass
107
- TestEnum = pool.lookup("TestEnum").enummodule
108
23
  BadFieldNames = pool.lookup("BadFieldNames").msgclass
109
- MapMessage = pool.lookup("MapMessage").msgclass
110
- MapMessageWireEquiv = pool.lookup("MapMessageWireEquiv").msgclass
111
- MapMessageWireEquiv_entry1 =
112
- pool.lookup("MapMessageWireEquiv_entry1").msgclass
113
- MapMessageWireEquiv_entry2 =
114
- pool.lookup("MapMessageWireEquiv_entry2").msgclass
115
- OneofMessage = pool.lookup("OneofMessage").msgclass
116
24
 
117
25
  # ------------ test cases ---------------
118
26
 
119
27
  class MessageContainerTest < Test::Unit::TestCase
120
-
121
- def test_defaults
122
- m = TestMessage.new
123
- assert m.optional_int32 == 0
124
- assert m.optional_int64 == 0
125
- assert m.optional_uint32 == 0
126
- assert m.optional_uint64 == 0
127
- assert m.optional_bool == false
128
- assert m.optional_float == 0.0
129
- assert m.optional_double == 0.0
130
- assert m.optional_string == ""
131
- assert m.optional_bytes == ""
132
- assert m.optional_msg == nil
133
- assert m.optional_enum == :Default
134
- end
135
-
136
- def test_setters
137
- m = TestMessage.new
138
- m.optional_int32 = -42
139
- assert m.optional_int32 == -42
140
- m.optional_int64 = -0x1_0000_0000
141
- assert m.optional_int64 == -0x1_0000_0000
142
- m.optional_uint32 = 0x9000_0000
143
- assert m.optional_uint32 == 0x9000_0000
144
- m.optional_uint64 = 0x9000_0000_0000_0000
145
- assert m.optional_uint64 == 0x9000_0000_0000_0000
146
- m.optional_bool = true
147
- assert m.optional_bool == true
148
- m.optional_float = 0.5
149
- assert m.optional_float == 0.5
150
- m.optional_double = 0.5
151
- m.optional_string = "hello"
152
- assert m.optional_string == "hello"
153
- m.optional_bytes = "world".encode!('ASCII-8BIT')
154
- assert m.optional_bytes == "world"
155
- m.optional_msg = TestMessage2.new(:foo => 42)
156
- assert m.optional_msg == TestMessage2.new(:foo => 42)
157
- m.optional_msg = nil
158
- assert m.optional_msg == nil
159
- end
160
-
161
- def test_ctor_args
162
- m = TestMessage.new(:optional_int32 => -42,
163
- :optional_msg => TestMessage2.new,
164
- :optional_enum => :C,
165
- :repeated_string => ["hello", "there", "world"])
166
- assert m.optional_int32 == -42
167
- assert m.optional_msg.class == TestMessage2
168
- assert m.repeated_string.length == 3
169
- assert m.optional_enum == :C
170
- assert m.repeated_string[0] == "hello"
171
- assert m.repeated_string[1] == "there"
172
- assert m.repeated_string[2] == "world"
173
- end
174
-
175
- def test_inspect
176
- m = TestMessage.new(:optional_int32 => -42,
177
- :optional_enum => :A,
178
- :optional_msg => TestMessage2.new,
179
- :repeated_string => ["hello", "there", "world"])
180
- expected = '<BasicTest::TestMessage: optional_int32: -42, optional_int64: 0, optional_uint32: 0, optional_uint64: 0, optional_bool: false, optional_float: 0.0, optional_double: 0.0, optional_string: "", optional_bytes: "", optional_msg: <BasicTest::TestMessage2: foo: 0>, optional_enum: :A, repeated_int32: [], repeated_int64: [], repeated_uint32: [], repeated_uint64: [], repeated_bool: [], repeated_float: [], repeated_double: [], repeated_string: ["hello", "there", "world"], repeated_bytes: [], repeated_msg: [], repeated_enum: []>'
181
- assert_equal expected, m.inspect
182
- end
183
-
184
- def test_hash
185
- m1 = TestMessage.new(:optional_int32 => 42)
186
- m2 = TestMessage.new(:optional_int32 => 102, repeated_string: ['please', 'work', 'ok?'])
187
- m3 = TestMessage.new(:optional_int32 => 102, repeated_string: ['please', 'work', 'ok?'])
188
- assert m1.hash != 0
189
- assert m2.hash != 0
190
- assert m3.hash != 0
191
- # relying on the randomness here -- if hash function changes and we are
192
- # unlucky enough to get a collision, then change the values above.
193
- assert m1.hash != m2.hash
194
- assert_equal m2.hash, m3.hash
195
- end
196
-
197
- def test_unknown_field_errors
198
- e = assert_raise NoMethodError do
199
- TestMessage.new.hello
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
200
43
  end
201
- assert_match(/hello/, e.message)
202
44
 
203
- e = assert_raise NoMethodError do
204
- TestMessage.new.hello = "world"
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
205
51
  end
206
- assert_match(/hello/, e.message)
207
- end
208
52
 
209
- def test_initialization_map_errors
210
- e = assert_raise ArgumentError do
211
- TestMessage.new(:hello => "world")
212
- end
213
- assert_match(/hello/, e.message)
53
+ outer = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("Outer").msgclass
214
54
 
215
- e = assert_raise ArgumentError do
216
- MapMessage.new(:map_string_int32 => "hello")
217
- end
218
- assert_equal e.message, "Expected Hash object as initializer value for map field 'map_string_int32'."
55
+ outer.new(
56
+ inners: []
57
+ )['inners'].to_s
219
58
 
220
- e = assert_raise ArgumentError do
221
- TestMessage.new(:repeated_uint32 => "hello")
59
+ assert_raise Google::Protobuf::TypeError do
60
+ outer.new(
61
+ inners: [nil]
62
+ ).to_s
222
63
  end
223
- assert_equal e.message, "Expected array as initializer value for repeated field 'repeated_uint32'."
224
64
  end
225
65
 
226
- def test_type_errors
227
- m = TestMessage.new
228
- assert_raise TypeError do
229
- m.optional_int32 = "hello"
230
- end
231
- assert_raise TypeError do
232
- m.optional_string = 42
233
- end
234
- assert_raise TypeError do
235
- m.optional_string = nil
236
- end
237
- assert_raise TypeError do
238
- m.optional_bool = 42
239
- end
240
- assert_raise TypeError do
241
- m.optional_msg = TestMessage.new # expects TestMessage2
242
- end
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
243
73
 
244
- assert_raise TypeError do
245
- m.repeated_int32 = [] # needs RepeatedField
246
- end
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)
247
80
 
248
- assert_raise TypeError do
249
- m.repeated_int32.push "hello"
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?
250
87
  end
88
+ assert_true OneofMessage.descriptor.lookup('a').has?(m)
251
89
 
252
- assert_raise TypeError do
253
- m.repeated_msg.push TestMessage.new
90
+ m = TestSingularFields.new
91
+ assert_raise NoMethodError do
92
+ m.has_singular_int32?
254
93
  end
255
- end
256
-
257
- def test_string_encoding
258
- m = TestMessage.new
259
-
260
- # Assigning a normal (ASCII or UTF8) string to a bytes field, or
261
- # ASCII-8BIT to a string field will convert to the proper encoding.
262
- m.optional_bytes = "Test string ASCII".encode!('ASCII')
263
- assert m.optional_bytes.frozen?
264
- assert_equal Encoding::ASCII_8BIT, m.optional_bytes.encoding
265
- assert_equal "Test string ASCII", m.optional_bytes
266
-
267
- assert_raise Encoding::UndefinedConversionError do
268
- m.optional_bytes = "Test string UTF-8 \u0100".encode!('UTF-8')
94
+ assert_raise ArgumentError do
95
+ TestSingularFields.descriptor.lookup('singular_int32').has?(m)
269
96
  end
270
97
 
271
- assert_raise Encoding::UndefinedConversionError do
272
- m.optional_string = ["FFFF"].pack('H*')
98
+ assert_raise NoMethodError do
99
+ m.has_singular_string?
273
100
  end
274
-
275
- # "Ordinary" use case.
276
- m.optional_bytes = ["FFFF"].pack('H*')
277
- m.optional_string = "\u0100"
278
-
279
- # strings are immutable so we can't do this, but serialize should catch it.
280
- m.optional_string = "asdf".encode!('UTF-8')
281
- assert_raise RuntimeError do
282
- m.optional_string.encode!('ASCII-8BIT')
101
+ assert_raise ArgumentError do
102
+ TestSingularFields.descriptor.lookup('singular_string').has?(m)
283
103
  end
284
- end
285
104
 
286
- def test_rptfield_int32
287
- l = Google::Protobuf::RepeatedField.new(:int32)
288
- assert l.count == 0
289
- l = Google::Protobuf::RepeatedField.new(:int32, [1, 2, 3])
290
- assert l.count == 3
291
- assert_equal [1, 2, 3], l
292
- assert_equal l, [1, 2, 3]
293
- l.push 4
294
- assert l == [1, 2, 3, 4]
295
- dst_list = []
296
- l.each { |val| dst_list.push val }
297
- assert dst_list == [1, 2, 3, 4]
298
- assert l.to_a == [1, 2, 3, 4]
299
- assert l[0] == 1
300
- assert l[3] == 4
301
- l[0] = 5
302
- assert l == [5, 2, 3, 4]
303
-
304
- l2 = l.dup
305
- assert l == l2
306
- assert l.object_id != l2.object_id
307
- l2.push 6
308
- assert l.count == 4
309
- assert l2.count == 5
310
-
311
- assert l.inspect == '[5, 2, 3, 4]'
312
-
313
- l.concat([7, 8, 9])
314
- assert l == [5, 2, 3, 4, 7, 8, 9]
315
- assert l.pop == 9
316
- assert l == [5, 2, 3, 4, 7, 8]
317
-
318
- assert_raise TypeError do
319
- m = TestMessage.new
320
- l.push m
105
+ assert_raise NoMethodError do
106
+ m.has_singular_bool?
321
107
  end
322
-
323
- m = TestMessage.new
324
- m.repeated_int32 = l
325
- assert m.repeated_int32 == [5, 2, 3, 4, 7, 8]
326
- assert m.repeated_int32.object_id == l.object_id
327
- l.push 42
328
- assert m.repeated_int32.pop == 42
329
-
330
- l3 = l + l.dup
331
- assert l3.count == l.count * 2
332
- l.count.times do |i|
333
- assert l3[i] == l[i]
334
- assert l3[l.count + i] == l[i]
108
+ assert_raise ArgumentError do
109
+ TestSingularFields.descriptor.lookup('singular_bool').has?(m)
335
110
  end
336
111
 
337
- l.clear
338
- assert l.count == 0
339
- l += [1, 2, 3, 4]
340
- l.replace([5, 6, 7, 8])
341
- assert l == [5, 6, 7, 8]
342
-
343
- l4 = Google::Protobuf::RepeatedField.new(:int32)
344
- l4[5] = 42
345
- assert l4 == [0, 0, 0, 0, 0, 42]
346
-
347
- l4 << 100
348
- assert l4 == [0, 0, 0, 0, 0, 42, 100]
349
- l4 << 101 << 102
350
- assert l4 == [0, 0, 0, 0, 0, 42, 100, 101, 102]
351
- end
352
-
353
- def test_parent_rptfield
354
- #make sure we set the RepeatedField and can add to it
355
112
  m = TestMessage.new
356
- assert m.repeated_string == []
357
- m.repeated_string << 'ok'
358
- m.repeated_string.push('ok2')
359
- assert m.repeated_string == ['ok', 'ok2']
360
- m.repeated_string += ['ok3']
361
- assert m.repeated_string == ['ok', 'ok2', 'ok3']
362
- end
363
-
364
- def test_rptfield_msg
365
- l = Google::Protobuf::RepeatedField.new(:message, TestMessage)
366
- l.push TestMessage.new
367
- assert l.count == 1
368
- assert_raise TypeError do
369
- l.push TestMessage2.new
113
+ assert_raise NoMethodError do
114
+ m.has_repeated_msg?
370
115
  end
371
- assert_raise TypeError do
372
- l.push 42
116
+ assert_raise ArgumentError do
117
+ TestMessage.descriptor.lookup('repeated_msg').has?(m)
373
118
  end
374
-
375
- l2 = l.dup
376
- assert l2[0] == l[0]
377
- assert l2[0].object_id == l[0].object_id
378
-
379
- l2 = Google::Protobuf.deep_copy(l)
380
- assert l2[0] == l[0]
381
- assert l2[0].object_id != l[0].object_id
382
-
383
- l3 = l + l2
384
- assert l3.count == 2
385
- assert l3[0] == l[0]
386
- assert l3[1] == l2[0]
387
- l3[0].optional_int32 = 1000
388
- assert l[0].optional_int32 == 1000
389
-
390
- new_msg = TestMessage.new(:optional_int32 => 200)
391
- l4 = l + [new_msg]
392
- assert l4.count == 2
393
- new_msg.optional_int32 = 1000
394
- assert l4[1].optional_int32 == 1000
395
119
  end
396
120
 
397
- def test_rptfield_enum
398
- l = Google::Protobuf::RepeatedField.new(:enum, TestEnum)
399
- l.push :A
400
- l.push :B
401
- l.push :C
402
- assert l.count == 3
403
- assert_raise RangeError do
404
- l.push :D
405
- end
406
- assert l[0] == :A
121
+ def test_no_presence
122
+ m = TestSingularFields.new
407
123
 
408
- l.push 4
409
- assert l[3] == 4
410
- end
124
+ # Explicitly setting to zero does not cause anything to be serialized.
125
+ m.singular_int32 = 0
126
+ assert_equal "", TestSingularFields.encode(m)
411
127
 
412
- def test_rptfield_initialize
413
- assert_raise ArgumentError do
414
- l = Google::Protobuf::RepeatedField.new
415
- end
416
- assert_raise ArgumentError do
417
- l = Google::Protobuf::RepeatedField.new(:message)
418
- end
419
- assert_raise ArgumentError do
420
- l = Google::Protobuf::RepeatedField.new([1, 2, 3])
421
- end
422
- assert_raise ArgumentError do
423
- l = Google::Protobuf::RepeatedField.new(:message, [TestMessage2.new])
424
- end
425
- end
128
+ # Explicitly setting to a non-zero value *does* cause serialization.
129
+ m.singular_int32 = 1
130
+ assert_not_equal "", TestSingularFields.encode(m)
426
131
 
427
- def test_rptfield_array_ducktyping
428
- l = Google::Protobuf::RepeatedField.new(:int32)
429
- length_methods = %w(count length size)
430
- length_methods.each do |lm|
431
- assert l.send(lm) == 0
432
- end
433
- # out of bounds returns a nil
434
- assert l[0] == nil
435
- assert l[1] == nil
436
- assert l[-1] == nil
437
- l.push 4
438
- length_methods.each do |lm|
439
- assert l.send(lm) == 1
440
- end
441
- assert l[0] == 4
442
- assert l[1] == nil
443
- assert l[-1] == 4
444
- assert l[-2] == nil
445
-
446
- l.push 2
447
- length_methods.each do |lm|
448
- assert l.send(lm) == 2
449
- end
450
- assert l[0] == 4
451
- assert l[1] == 2
452
- assert l[2] == nil
453
- assert l[-1] == 2
454
- assert l[-2] == 4
455
- assert l[-3] == nil
456
-
457
- #adding out of scope will backfill with empty objects
132
+ m.singular_int32 = 0
133
+ assert_equal "", TestSingularFields.encode(m)
458
134
  end
459
135
 
460
- def test_map_basic
461
- # allowed key types:
462
- # :int32, :int64, :uint32, :uint64, :bool, :string, :bytes.
136
+ def test_set_clear_defaults
137
+ m = TestSingularFields.new
463
138
 
464
- m = Google::Protobuf::Map.new(:string, :int32)
465
- m["asdf"] = 1
466
- assert m["asdf"] == 1
467
- m["jkl;"] = 42
468
- assert m == { "jkl;" => 42, "asdf" => 1 }
469
- assert m.has_key?("asdf")
470
- assert !m.has_key?("qwerty")
471
- assert m.length == 2
139
+ m.singular_int32 = -42
140
+ assert_equal -42, m.singular_int32
141
+ m.clear_singular_int32
142
+ assert_equal 0, m.singular_int32
472
143
 
473
- m2 = m.dup
474
- assert_equal m, m2
475
- assert m.hash != 0
476
- assert_equal m.hash, m2.hash
477
-
478
- collected = {}
479
- m.each { |k,v| collected[v] = k }
480
- assert collected == { 42 => "jkl;", 1 => "asdf" }
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
481
148
 
482
- assert m.delete("asdf") == 1
483
- assert !m.has_key?("asdf")
484
- assert m["asdf"] == nil
485
- assert !m.has_key?("asdf")
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
486
153
 
487
- # We only assert on inspect value when there is one map entry because the
488
- # order in which elements appear is unspecified (depends on the internal
489
- # hash function). We don't want a brittle test.
490
- assert m.inspect == "{\"jkl;\"=>42}"
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
491
158
 
492
- assert m.keys == ["jkl;"]
493
- assert m.values == [42]
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?
494
165
 
495
- m.clear
496
- assert m.length == 0
497
- assert m == {}
498
-
499
- assert_raise TypeError do
500
- m[1] = 1
501
- end
502
- assert_raise RangeError do
503
- m["asdf"] = 0x1_0000_0000
504
- end
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
505
170
  end
506
171
 
507
- def test_map_ctor
508
- m = Google::Protobuf::Map.new(:string, :int32,
509
- {"a" => 1, "b" => 2, "c" => 3})
510
- assert m == {"a" => 1, "c" => 3, "b" => 2}
511
- end
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)
512
178
 
513
- def test_map_keytypes
514
- m = Google::Protobuf::Map.new(:int32, :int32)
515
- m[1] = 42
516
- m[-1] = 42
517
- assert_raise RangeError do
518
- m[0x8000_0000] = 1
519
- end
520
- assert_raise TypeError do
521
- m["asdf"] = 1
522
- end
179
+ m.clear_optional_proto2_submessage
180
+ assert !m.has_optional_proto2_submessage?
181
+ end
523
182
 
524
- m = Google::Protobuf::Map.new(:int64, :int32)
525
- m[0x1000_0000_0000_0000] = 1
526
- assert_raise RangeError do
527
- m[0x1_0000_0000_0000_0000] = 1
528
- end
529
- assert_raise TypeError do
530
- m["asdf"] = 1
531
- end
183
+ def test_clear_repeated_fields
184
+ m = TestMessage.new
532
185
 
533
- m = Google::Protobuf::Map.new(:uint32, :int32)
534
- m[0x8000_0000] = 1
535
- assert_raise RangeError do
536
- m[0x1_0000_0000] = 1
537
- end
538
- assert_raise RangeError do
539
- m[-1] = 1
540
- end
186
+ m.repeated_int32.push(1)
187
+ assert_equal [1], m.repeated_int32
188
+ m.clear_repeated_int32
189
+ assert_equal [], m.repeated_int32
541
190
 
542
- m = Google::Protobuf::Map.new(:uint64, :int32)
543
- m[0x8000_0000_0000_0000] = 1
544
- assert_raise RangeError do
545
- m[0x1_0000_0000_0000_0000] = 1
546
- end
547
- assert_raise RangeError do
548
- m[-1] = 1
549
- end
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
550
195
 
551
- m = Google::Protobuf::Map.new(:bool, :int32)
552
- m[true] = 1
553
- m[false] = 2
554
- assert_raise TypeError do
555
- m[1] = 1
556
- end
557
- assert_raise TypeError do
558
- m["asdf"] = 1
559
- end
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?
560
203
 
561
- m = Google::Protobuf::Map.new(:string, :int32)
562
- m["asdf"] = 1
563
- assert_raise TypeError do
564
- m[1] = 1
565
- end
566
- assert_raise Encoding::UndefinedConversionError do
567
- bytestring = ["FFFF"].pack("H*")
568
- m[bytestring] = 1
569
- end
204
+ m.a = "foobar"
205
+ assert m.has_my_oneof?
206
+ m.clear_my_oneof
207
+ assert !m.has_my_oneof?
570
208
 
571
- m = Google::Protobuf::Map.new(:bytes, :int32)
572
- bytestring = ["FFFF"].pack("H*")
573
- m[bytestring] = 1
574
- # Allowed -- we will automatically convert to ASCII-8BIT.
575
- m["asdf"] = 1
576
- assert_raise TypeError do
577
- m[1] = 1
578
- end
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?
579
214
  end
580
215
 
581
- def test_map_msg_enum_valuetypes
582
- m = Google::Protobuf::Map.new(:string, :message, TestMessage)
583
- m["asdf"] = TestMessage.new
584
- assert_raise TypeError do
585
- m["jkl;"] = TestMessage2.new
216
+ def test_initialization_map_errors
217
+ e = assert_raise ArgumentError do
218
+ TestMessage.new(:hello => "world")
586
219
  end
220
+ assert_match(/hello/, e.message)
587
221
 
588
- m = Google::Protobuf::Map.new(
589
- :string, :message, TestMessage,
590
- { "a" => TestMessage.new(:optional_int32 => 42),
591
- "b" => TestMessage.new(:optional_int32 => 84) })
592
- assert m.length == 2
593
- assert m.values.map{|msg| msg.optional_int32}.sort == [42, 84]
594
-
595
- m = Google::Protobuf::Map.new(:string, :enum, TestEnum,
596
- { "x" => :A, "y" => :B, "z" => :C })
597
- assert m.length == 3
598
- assert m["z"] == :C
599
- m["z"] = 2
600
- assert m["z"] == :B
601
- m["z"] = 4
602
- assert m["z"] == 4
603
- assert_raise RangeError do
604
- m["z"] = :Z
605
- end
606
- assert_raise TypeError do
607
- m["z"] = "z"
222
+ e = assert_raise ArgumentError do
223
+ MapMessage.new(:map_string_int32 => "hello")
608
224
  end
609
- end
225
+ assert_equal e.message, "Expected Hash object as initializer value for map field 'map_string_int32' (given String)."
610
226
 
611
- def test_map_dup_deep_copy
612
- m = Google::Protobuf::Map.new(
613
- :string, :message, TestMessage,
614
- { "a" => TestMessage.new(:optional_int32 => 42),
615
- "b" => TestMessage.new(:optional_int32 => 84) })
616
-
617
- m2 = m.dup
618
- assert m == m2
619
- assert m.object_id != m2.object_id
620
- assert m["a"].object_id == m2["a"].object_id
621
- assert m["b"].object_id == m2["b"].object_id
622
-
623
- m2 = Google::Protobuf.deep_copy(m)
624
- assert m == m2
625
- assert m.object_id != m2.object_id
626
- assert m["a"].object_id != m2["a"].object_id
627
- assert m["b"].object_id != m2["b"].object_id
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)."
628
231
  end
629
232
 
630
233
  def test_map_field
@@ -635,10 +238,12 @@ module BasicTest
635
238
  m = MapMessage.new(
636
239
  :map_string_int32 => {"a" => 1, "b" => 2},
637
240
  :map_string_msg => {"a" => TestMessage2.new(:foo => 1),
638
- "b" => TestMessage2.new(:foo => 2)})
241
+ "b" => TestMessage2.new(:foo => 2)},
242
+ :map_string_enum => {"a" => :A, "b" => :B})
639
243
  assert m.map_string_int32.keys.sort == ["a", "b"]
640
244
  assert m.map_string_int32["a"] == 1
641
245
  assert m.map_string_msg["b"].foo == 2
246
+ assert m.map_string_enum["a"] == :A
642
247
 
643
248
  m.map_string_int32["c"] = 3
644
249
  assert m.map_string_int32["c"] == 3
@@ -648,25 +253,53 @@ module BasicTest
648
253
  m.map_string_msg.delete("c")
649
254
  assert m.map_string_msg == { "a" => TestMessage2.new(:foo => 1) }
650
255
 
651
- assert_raise TypeError do
256
+ assert_raise Google::Protobuf::TypeError do
652
257
  m.map_string_msg["e"] = TestMessage.new # wrong value type
653
258
  end
654
259
  # ensure nothing was added by the above
655
260
  assert m.map_string_msg == { "a" => TestMessage2.new(:foo => 1) }
656
261
 
657
262
  m.map_string_int32 = Google::Protobuf::Map.new(:string, :int32)
658
- assert_raise TypeError do
263
+ assert_raise Google::Protobuf::TypeError do
659
264
  m.map_string_int32 = Google::Protobuf::Map.new(:string, :int64)
660
265
  end
661
- assert_raise TypeError do
266
+ assert_raise Google::Protobuf::TypeError do
662
267
  m.map_string_int32 = {}
663
268
  end
664
269
 
665
- assert_raise TypeError do
270
+ assert_raise Google::Protobuf::TypeError do
666
271
  m = MapMessage.new(:map_string_int32 => { 1 => "I am not a number" })
667
272
  end
668
273
  end
669
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
+
670
303
  def test_map_corruption
671
304
  # This pattern led to a crash in a previous version of upb/protobuf.
672
305
  m = MapMessage.new(map_string_int32: { "aaa" => 1 })
@@ -674,11 +307,149 @@ module BasicTest
674
307
  m.map_string_int32['aaa'] = 3
675
308
  end
676
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
+
677
447
  def test_map_encode_decode
678
448
  m = MapMessage.new(
679
449
  :map_string_int32 => {"a" => 1, "b" => 2},
680
450
  :map_string_msg => {"a" => TestMessage2.new(:foo => 1),
681
- "b" => TestMessage2.new(:foo => 2)})
451
+ "b" => TestMessage2.new(:foo => 2)},
452
+ :map_string_enum => {"a" => :A, "b" => :B})
682
453
  m2 = MapMessage.decode(MapMessage.encode(m))
683
454
  assert m == m2
684
455
 
@@ -695,213 +466,29 @@ module BasicTest
695
466
  "b" => TestMessage2.new(:foo => 2)}
696
467
  end
697
468
 
698
- def test_oneof_descriptors
699
- d = OneofMessage.descriptor
700
- o = d.lookup_oneof("my_oneof")
701
- assert o != nil
702
- assert o.class == Google::Protobuf::OneofDescriptor
703
- assert o.name == "my_oneof"
704
- oneof_count = 0
705
- d.each_oneof{ |oneof|
706
- oneof_count += 1
707
- assert oneof == o
708
- }
709
- assert oneof_count == 1
710
- assert o.count == 4
711
- field_names = o.map{|f| f.name}.sort
712
- assert field_names == ["a", "b", "c", "d"]
713
- end
714
-
715
- def test_oneof
716
- d = OneofMessage.new
717
- assert d.a == ""
718
- assert d.b == 0
719
- assert d.c == nil
720
- assert d.d == :Default
721
- assert d.my_oneof == nil
722
-
723
- d.a = "hi"
724
- assert d.a == "hi"
725
- assert d.b == 0
726
- assert d.c == nil
727
- assert d.d == :Default
728
- assert d.my_oneof == :a
729
-
730
- d.b = 42
731
- assert d.a == ""
732
- assert d.b == 42
733
- assert d.c == nil
734
- assert d.d == :Default
735
- assert d.my_oneof == :b
736
-
737
- d.c = TestMessage2.new(:foo => 100)
738
- assert d.a == ""
739
- assert d.b == 0
740
- assert d.c.foo == 100
741
- assert d.d == :Default
742
- assert d.my_oneof == :c
743
-
744
- d.d = :C
745
- assert d.a == ""
746
- assert d.b == 0
747
- assert d.c == nil
748
- assert d.d == :C
749
- assert d.my_oneof == :d
750
-
751
- d2 = OneofMessage.decode(OneofMessage.encode(d))
752
- assert d2 == d
753
-
754
- encoded_field_a = OneofMessage.encode(OneofMessage.new(:a => "string"))
755
- encoded_field_b = OneofMessage.encode(OneofMessage.new(:b => 1000))
756
- encoded_field_c = OneofMessage.encode(
757
- OneofMessage.new(:c => TestMessage2.new(:foo => 1)))
758
- encoded_field_d = OneofMessage.encode(OneofMessage.new(:d => :B))
759
-
760
- d3 = OneofMessage.decode(
761
- encoded_field_c + encoded_field_a + encoded_field_d)
762
- assert d3.a == ""
763
- assert d3.b == 0
764
- assert d3.c == nil
765
- assert d3.d == :B
766
-
767
- d4 = OneofMessage.decode(
768
- encoded_field_c + encoded_field_a + encoded_field_d +
769
- encoded_field_c)
770
- assert d4.a == ""
771
- assert d4.b == 0
772
- assert d4.c.foo == 1
773
- assert d4.d == :Default
774
-
775
- d5 = OneofMessage.new(:a => "hello")
776
- assert d5.a == "hello"
777
- d5.a = nil
778
- assert d5.a == ""
779
- assert OneofMessage.encode(d5) == ''
780
- assert d5.my_oneof == nil
781
- end
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 })
782
474
 
783
- def test_enum_field
784
- m = TestMessage.new
785
- assert m.optional_enum == :Default
786
- m.optional_enum = :A
787
- assert m.optional_enum == :A
788
- assert_raise RangeError do
789
- m.optional_enum = :ASDF
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)
790
478
  end
791
- m.optional_enum = 1
792
- assert m.optional_enum == :A
793
- m.optional_enum = 100
794
- assert m.optional_enum == 100
479
+ assert_match(/No such field: not_in_message/, e.message)
795
480
  end
796
481
 
797
- def test_dup
798
- m = TestMessage.new
799
- m.optional_string = "hello"
800
- m.optional_int32 = 42
801
- tm1 = TestMessage2.new(:foo => 100)
802
- tm2 = TestMessage2.new(:foo => 200)
803
- m.repeated_msg.push tm1
804
- assert m.repeated_msg[-1] == tm1
805
- m.repeated_msg.push tm2
806
- assert m.repeated_msg[-1] == tm2
807
- m2 = m.dup
808
- assert m == m2
809
- m.optional_int32 += 1
810
- assert m != m2
811
- assert m.repeated_msg[0] == m2.repeated_msg[0]
812
- assert m.repeated_msg[0].object_id == m2.repeated_msg[0].object_id
813
- end
814
-
815
- def test_deep_copy
816
- m = TestMessage.new(:optional_int32 => 42,
817
- :repeated_msg => [TestMessage2.new(:foo => 100)])
818
- m2 = Google::Protobuf.deep_copy(m)
819
- assert m == m2
820
- assert m.repeated_msg == m2.repeated_msg
821
- assert m.repeated_msg.object_id != m2.repeated_msg.object_id
822
- assert m.repeated_msg[0].object_id != m2.repeated_msg[0].object_id
823
- end
824
-
825
- def test_eq
826
- m = TestMessage.new(:optional_int32 => 42,
827
- :repeated_int32 => [1, 2, 3])
828
- m2 = TestMessage.new(:optional_int32 => 43,
829
- :repeated_int32 => [1, 2, 3])
830
- assert m != m2
831
- end
832
-
833
- def test_enum_lookup
834
- assert TestEnum::A == 1
835
- assert TestEnum::B == 2
836
- assert TestEnum::C == 3
837
-
838
- assert TestEnum::lookup(1) == :A
839
- assert TestEnum::lookup(2) == :B
840
- assert TestEnum::lookup(3) == :C
841
-
842
- assert TestEnum::resolve(:A) == 1
843
- assert TestEnum::resolve(:B) == 2
844
- assert TestEnum::resolve(:C) == 3
845
- end
846
-
847
- def test_parse_serialize
848
- m = TestMessage.new(:optional_int32 => 42,
849
- :optional_string => "hello world",
850
- :optional_enum => :B,
851
- :repeated_string => ["a", "b", "c"],
852
- :repeated_int32 => [42, 43, 44],
853
- :repeated_enum => [:A, :B, :C, 100],
854
- :repeated_msg => [TestMessage2.new(:foo => 1),
855
- TestMessage2.new(:foo => 2)])
856
- data = TestMessage.encode m
857
- m2 = TestMessage.decode data
858
- assert m == m2
859
-
860
- data = Google::Protobuf.encode m
861
- m2 = Google::Protobuf.decode(TestMessage, data)
862
- assert m == m2
863
- end
864
-
865
- def test_encode_decode_helpers
866
- m = TestMessage.new(:optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
867
- assert_equal 'foo', m.optional_string
868
- assert_equal ['bar1', 'bar2'], m.repeated_string
869
-
870
- json = m.to_json
871
- m2 = TestMessage.decode_json(json)
872
- assert_equal 'foo', m2.optional_string
873
- assert_equal ['bar1', 'bar2'], m2.repeated_string
874
- if RUBY_PLATFORM != "java"
875
- assert m2.optional_string.frozen?
876
- assert m2.repeated_string[0].frozen?
877
- end
878
-
879
- proto = m.to_proto
880
- m2 = TestMessage.decode(proto)
881
- assert_equal 'foo', m2.optional_string
882
- assert_equal ['bar1', 'bar2'], m2.repeated_string
883
- end
884
-
885
- def test_protobuf_encode_decode_helpers
886
- m = TestMessage.new(:optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
887
- encoded_msg = Google::Protobuf.encode(m)
888
- assert_equal m.to_proto, encoded_msg
889
-
890
- decoded_msg = Google::Protobuf.decode(TestMessage, encoded_msg)
891
- assert_equal TestMessage.decode(m.to_proto), decoded_msg
892
- end
893
-
894
- def test_protobuf_encode_decode_json_helpers
895
- m = TestMessage.new(:optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
896
- encoded_msg = Google::Protobuf.encode_json(m)
897
- assert_equal m.to_json, encoded_msg
898
-
899
- decoded_msg = Google::Protobuf.decode_json(TestMessage, encoded_msg)
900
- assert_equal TestMessage.decode_json(m.to_json), decoded_msg
901
- end
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
902
489
 
903
490
  def test_to_h
904
- m = TestMessage.new(:optional_bool => true, :optional_double => -10.100001, :optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
491
+ m = TestMessage.new(:optional_bool => true, :optional_double => -10.100001, :optional_string => 'foo', :repeated_string => ['bar1', 'bar2'], :repeated_msg => [TestMessage2.new(:foo => 100)])
905
492
  expected_result = {
906
493
  :optional_bool=>true,
907
494
  :optional_bytes=>"",
@@ -911,6 +498,8 @@ module BasicTest
911
498
  :optional_int32=>0,
912
499
  :optional_int64=>0,
913
500
  :optional_msg=>nil,
501
+ :optional_msg2=>nil,
502
+ :optional_proto2_submessage=>nil,
914
503
  :optional_string=>"foo",
915
504
  :optional_uint32=>0,
916
505
  :optional_uint64=>0,
@@ -921,276 +510,75 @@ module BasicTest
921
510
  :repeated_float=>[],
922
511
  :repeated_int32=>[],
923
512
  :repeated_int64=>[],
924
- :repeated_msg=>[],
513
+ :repeated_msg=>[{:foo => 100}],
925
514
  :repeated_string=>["bar1", "bar2"],
926
515
  :repeated_uint32=>[],
927
516
  :repeated_uint64=>[]
928
517
  }
929
518
  assert_equal expected_result, m.to_h
930
- end
931
519
 
932
-
933
- def test_def_errors
934
- s = Google::Protobuf::DescriptorPool.new
935
- assert_raise TypeError do
936
- s.build do
937
- # enum with no default (integer value 0)
938
- add_enum "MyEnum" do
939
- value :A, 1
940
- end
941
- end
942
- end
943
- assert_raise TypeError do
944
- s.build do
945
- # message with required field (unsupported in proto3)
946
- add_message "MyMessage" do
947
- required :foo, :int32, 1
948
- end
949
- end
950
- end
951
- end
952
-
953
- def test_corecursive
954
- # just be sure that we can instantiate types with corecursive field-type
955
- # references.
956
- m = Recursive1.new(:foo => Recursive2.new(:foo => Recursive1.new))
957
- assert Recursive1.descriptor.lookup("foo").subtype ==
958
- Recursive2.descriptor
959
- assert Recursive2.descriptor.lookup("foo").subtype ==
960
- Recursive1.descriptor
961
-
962
- serialized = Recursive1.encode(m)
963
- m2 = Recursive1.decode(serialized)
964
- assert m == m2
965
- end
966
-
967
- def test_serialize_cycle
968
- m = Recursive1.new(:foo => Recursive2.new)
969
- m.foo.foo = m
970
- assert_raise RuntimeError do
971
- serialized = Recursive1.encode(m)
972
- end
973
- end
974
-
975
- def test_bad_field_names
976
- m = BadFieldNames.new(:dup => 1, :class => 2)
977
- m2 = m.dup
978
- assert m == m2
979
- assert m['dup'] == 1
980
- assert m['class'] == 2
981
- m['dup'] = 3
982
- assert m['dup'] == 3
983
- m['a.b'] = 4
984
- assert m['a.b'] == 4
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
985
531
  end
986
532
 
987
- def test_int_ranges
988
- m = TestMessage.new
989
-
990
- m.optional_int32 = 0
991
- m.optional_int32 = -0x8000_0000
992
- m.optional_int32 = +0x7fff_ffff
993
- m.optional_int32 = 1.0
994
- m.optional_int32 = -1.0
995
- m.optional_int32 = 2e9
996
- assert_raise RangeError do
997
- m.optional_int32 = -0x8000_0001
998
- end
999
- assert_raise RangeError do
1000
- m.optional_int32 = +0x8000_0000
1001
- end
1002
- assert_raise RangeError do
1003
- m.optional_int32 = +0x1000_0000_0000_0000_0000_0000 # force Bignum
1004
- end
1005
- assert_raise RangeError do
1006
- m.optional_int32 = 1e12
1007
- end
1008
- assert_raise RangeError do
1009
- m.optional_int32 = 1.5
1010
- end
1011
-
1012
- m.optional_uint32 = 0
1013
- m.optional_uint32 = +0xffff_ffff
1014
- m.optional_uint32 = 1.0
1015
- m.optional_uint32 = 4e9
1016
- assert_raise RangeError do
1017
- m.optional_uint32 = -1
1018
- end
1019
- assert_raise RangeError do
1020
- m.optional_uint32 = -1.5
1021
- end
1022
- assert_raise RangeError do
1023
- m.optional_uint32 = -1.5e12
1024
- end
1025
- assert_raise RangeError do
1026
- m.optional_uint32 = -0x1000_0000_0000_0000
1027
- end
1028
- assert_raise RangeError do
1029
- m.optional_uint32 = +0x1_0000_0000
1030
- end
1031
- assert_raise RangeError do
1032
- m.optional_uint32 = +0x1000_0000_0000_0000_0000_0000 # force Bignum
1033
- end
1034
- assert_raise RangeError do
1035
- m.optional_uint32 = 1e12
1036
- end
1037
- assert_raise RangeError do
1038
- m.optional_uint32 = 1.5
1039
- end
1040
-
1041
- m.optional_int64 = 0
1042
- m.optional_int64 = -0x8000_0000_0000_0000
1043
- m.optional_int64 = +0x7fff_ffff_ffff_ffff
1044
- m.optional_int64 = 1.0
1045
- m.optional_int64 = -1.0
1046
- m.optional_int64 = 8e18
1047
- m.optional_int64 = -8e18
1048
- assert_raise RangeError do
1049
- m.optional_int64 = -0x8000_0000_0000_0001
1050
- end
1051
- assert_raise RangeError do
1052
- m.optional_int64 = +0x8000_0000_0000_0000
1053
- end
1054
- assert_raise RangeError do
1055
- m.optional_int64 = +0x1000_0000_0000_0000_0000_0000 # force Bignum
1056
- end
1057
- assert_raise RangeError do
1058
- m.optional_int64 = 1e50
1059
- end
1060
- assert_raise RangeError do
1061
- m.optional_int64 = 1.5
1062
- end
1063
533
 
1064
- m.optional_uint64 = 0
1065
- m.optional_uint64 = +0xffff_ffff_ffff_ffff
1066
- m.optional_uint64 = 1.0
1067
- m.optional_uint64 = 16e18
1068
- assert_raise RangeError do
1069
- m.optional_uint64 = -1
1070
- end
1071
- assert_raise RangeError do
1072
- m.optional_uint64 = -1.5
1073
- end
1074
- assert_raise RangeError do
1075
- m.optional_uint64 = -1.5e12
1076
- end
1077
- assert_raise RangeError do
1078
- m.optional_uint64 = -0x1_0000_0000_0000_0000
1079
- end
1080
- assert_raise RangeError do
1081
- m.optional_uint64 = +0x1_0000_0000_0000_0000
1082
- end
1083
- assert_raise RangeError do
1084
- m.optional_uint64 = +0x1000_0000_0000_0000_0000_0000 # force Bignum
1085
- end
1086
- assert_raise RangeError do
1087
- m.optional_uint64 = 1e50
1088
- end
1089
- assert_raise RangeError do
1090
- m.optional_uint64 = 1.5
1091
- end
1092
- end
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
1093
541
 
1094
- def test_stress_test
1095
- m = TestMessage.new
1096
- m.optional_int32 = 42
1097
- m.optional_int64 = 0x100000000
1098
- m.optional_string = "hello world"
1099
- 10.times do m.repeated_msg.push TestMessage2.new(:foo => 42) end
1100
- 10.times do m.repeated_string.push "hello world" end
1101
-
1102
- data = TestMessage.encode(m)
1103
-
1104
- l = 0
1105
- 10_000.times do
1106
- m = TestMessage.decode(data)
1107
- data_new = TestMessage.encode(m)
1108
- assert data_new == data
1109
- data = data_new
1110
- end
1111
- end
542
+ json = MapMessage.encode_json(m, :preserve_proto_fieldnames => true, :emit_defaults=>true)
543
+ assert_equal JSON.parse(json, :symbolize_names => true), expected_preserve
1112
544
 
1113
- def test_reflection
1114
- m = TestMessage.new(:optional_int32 => 1234)
1115
- msgdef = m.class.descriptor
1116
- assert msgdef.class == Google::Protobuf::Descriptor
1117
- assert msgdef.any? {|field| field.name == "optional_int32"}
1118
- optional_int32 = msgdef.lookup "optional_int32"
1119
- assert optional_int32.class == Google::Protobuf::FieldDescriptor
1120
- assert optional_int32 != nil
1121
- assert optional_int32.name == "optional_int32"
1122
- assert optional_int32.type == :int32
1123
- optional_int32.set(m, 5678)
1124
- assert m.optional_int32 == 5678
1125
- m.optional_int32 = 1000
1126
- assert optional_int32.get(m) == 1000
1127
-
1128
- optional_msg = msgdef.lookup "optional_msg"
1129
- assert optional_msg.subtype == TestMessage2.descriptor
1130
-
1131
- optional_msg.set(m, optional_msg.subtype.msgclass.new)
1132
-
1133
- assert msgdef.msgclass == TestMessage
1134
-
1135
- optional_enum = msgdef.lookup "optional_enum"
1136
- assert optional_enum.subtype == TestEnum.descriptor
1137
- assert optional_enum.subtype.class == Google::Protobuf::EnumDescriptor
1138
- optional_enum.subtype.each do |k, v|
1139
- # set with integer, check resolution to symbolic name
1140
- optional_enum.set(m, v)
1141
- assert optional_enum.get(m) == k
1142
- end
545
+ m2 = MapMessage.decode_json(MapMessage.encode_json(m))
546
+ assert_equal m, m2
1143
547
  end
1144
548
 
1145
- def test_json
549
+ def test_json_maps_emit_defaults_submsg
1146
550
  # TODO: Fix JSON in JRuby version.
1147
551
  return if RUBY_PLATFORM == "java"
1148
- m = TestMessage.new(:optional_int32 => 1234,
1149
- :optional_int64 => -0x1_0000_0000,
1150
- :optional_uint32 => 0x8000_0000,
1151
- :optional_uint64 => 0xffff_ffff_ffff_ffff,
1152
- :optional_bool => true,
1153
- :optional_float => 1.0,
1154
- :optional_double => -1e100,
1155
- :optional_string => "Test string",
1156
- :optional_bytes => ["FFFFFFFF"].pack('H*'),
1157
- :optional_msg => TestMessage2.new(:foo => 42),
1158
- :repeated_int32 => [1, 2, 3, 4],
1159
- :repeated_string => ["a", "b", "c"],
1160
- :repeated_bool => [true, false, true, false],
1161
- :repeated_msg => [TestMessage2.new(:foo => 1),
1162
- TestMessage2.new(:foo => 2)])
1163
-
1164
- json_text = TestMessage.encode_json(m)
1165
- m2 = TestMessage.decode_json(json_text)
1166
- assert m == m2
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)
1167
556
 
1168
- # Crash case from GitHub issue 283.
1169
- bar = Bar.new(msg: "bar")
1170
- baz1 = Baz.new(msg: "baz")
1171
- baz2 = Baz.new(msg: "quux")
1172
- Foo.encode_json(Foo.new)
1173
- Foo.encode_json(Foo.new(bar: bar))
1174
- Foo.encode_json(Foo.new(bar: bar, baz: [baz1, baz2]))
557
+ assert_equal JSON.parse(actual, :symbolize_names => true), expected
1175
558
  end
1176
559
 
1177
- def test_json_maps
560
+ def test_json_emit_defaults_submsg
1178
561
  # TODO: Fix JSON in JRuby version.
1179
562
  return if RUBY_PLATFORM == "java"
1180
- m = MapMessage.new(:map_string_int32 => {"a" => 1})
1181
- expected = '{"mapStringInt32":{"a":1},"mapStringMsg":{}}'
1182
- expected_preserve = '{"map_string_int32":{"a":1},"map_string_msg":{}}'
1183
- assert MapMessage.encode_json(m) == expected
1184
-
1185
- json = MapMessage.encode_json(m, :preserve_proto_fieldnames => true)
1186
- assert json == expected_preserve
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
+ }
1187
578
 
1188
- m2 = MapMessage.decode_json(MapMessage.encode_json(m))
1189
- assert m == m2
1190
- end
579
+ actual = proto_module::TestMessage.encode_json(m, :emit_defaults => true)
1191
580
 
1192
- def test_comparison_with_arbitrary_object
1193
- assert MapMessage.new != nil
581
+ assert_equal expected, JSON.parse(actual, :symbolize_names => true)
1194
582
  end
1195
583
 
1196
584
  def test_respond_to
@@ -1200,5 +588,53 @@ module BasicTest
1200
588
  assert msg.respond_to?(:map_string_int32)
1201
589
  assert !msg.respond_to?(:bacon)
1202
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
1203
639
  end
1204
640
  end