google-protobuf 3.6.1 → 3.9.1

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.

@@ -1,5 +1,10 @@
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'
4
9
  require 'json'
5
10
  require 'test/unit'
@@ -9,682 +14,152 @@ require 'test/unit'
9
14
  module BasicTest
10
15
  pool = Google::Protobuf::DescriptorPool.new
11
16
  pool.build do
12
- add_message "Foo" do
13
- optional :bar, :message, 1, "Bar"
14
- repeated :baz, :message, 2, "Baz"
15
- end
16
-
17
- add_message "Bar" do
18
- optional :msg, :string, 1
19
- end
20
-
21
- add_message "Baz" do
22
- optional :msg, :string, 1
23
- end
24
-
25
- add_message "TestMessage" do
26
- optional :optional_int32, :int32, 1
27
- optional :optional_int64, :int64, 2
28
- optional :optional_uint32, :uint32, 3
29
- optional :optional_uint64, :uint64, 4
30
- optional :optional_bool, :bool, 5
31
- optional :optional_float, :float, 6
32
- optional :optional_double, :double, 7
33
- optional :optional_string, :string, 8
34
- optional :optional_bytes, :bytes, 9
35
- optional :optional_msg, :message, 10, "TestMessage2"
36
- optional :optional_enum, :enum, 11, "TestEnum"
37
-
38
- repeated :repeated_int32, :int32, 12
39
- repeated :repeated_int64, :int64, 13
40
- repeated :repeated_uint32, :uint32, 14
41
- repeated :repeated_uint64, :uint64, 15
42
- repeated :repeated_bool, :bool, 16
43
- repeated :repeated_float, :float, 17
44
- repeated :repeated_double, :double, 18
45
- repeated :repeated_string, :string, 19
46
- repeated :repeated_bytes, :bytes, 20
47
- repeated :repeated_msg, :message, 21, "TestMessage2"
48
- repeated :repeated_enum, :enum, 22, "TestEnum"
49
- end
50
- add_message "TestMessage2" do
51
- optional :foo, :int32, 1
52
- end
53
-
54
- add_message "TestEmbeddedMessageParent" do
55
- optional :child_msg, :message, 1, "TestEmbeddedMessageChild"
56
- optional :number, :int32, 2
57
-
58
- repeated :repeated_msg, :message, 3, "TestEmbeddedMessageChild"
59
- repeated :repeated_number, :int32, 4
60
- end
61
- add_message "TestEmbeddedMessageChild" do
62
- optional :sub_child, :message, 1, "TestMessage"
63
- end
64
-
65
- add_message "Recursive1" do
66
- optional :foo, :message, 1, "Recursive2"
67
- end
68
- add_message "Recursive2" do
69
- optional :foo, :message, 1, "Recursive1"
70
- end
71
-
72
- add_enum "TestEnum" do
73
- value :Default, 0
74
- value :A, 1
75
- value :B, 2
76
- value :C, 3
77
- end
78
-
79
17
  add_message "BadFieldNames" do
80
18
  optional :dup, :int32, 1
81
19
  optional :class, :int32, 2
82
20
  optional :"a.b", :int32, 3
83
21
  end
84
-
85
- add_message "MapMessage" do
86
- map :map_string_int32, :string, :int32, 1
87
- map :map_string_msg, :string, :message, 2, "TestMessage2"
88
- end
89
- add_message "MapMessageWireEquiv" do
90
- repeated :map_string_int32, :message, 1, "MapMessageWireEquiv_entry1"
91
- repeated :map_string_msg, :message, 2, "MapMessageWireEquiv_entry2"
92
- end
93
- add_message "MapMessageWireEquiv_entry1" do
94
- optional :key, :string, 1
95
- optional :value, :int32, 2
96
- end
97
- add_message "MapMessageWireEquiv_entry2" do
98
- optional :key, :string, 1
99
- optional :value, :message, 2, "TestMessage2"
100
- end
101
-
102
- add_message "OneofMessage" do
103
- oneof :my_oneof do
104
- optional :a, :string, 1
105
- optional :b, :int32, 2
106
- optional :c, :message, 3, "TestMessage2"
107
- optional :d, :enum, 4, "TestEnum"
108
- end
109
- end
110
-
111
- add_message "repro.Outer" do
112
- map :items, :int32, :message, 1, "repro.Inner"
113
- end
114
-
115
- add_message "repro.Inner" do
116
- end
117
22
  end
118
23
 
119
-
120
- Outer = pool.lookup("repro.Outer").msgclass
121
- Inner = pool.lookup("repro.Inner").msgclass
122
- Foo = pool.lookup("Foo").msgclass
123
- Bar = pool.lookup("Bar").msgclass
124
- Baz = pool.lookup("Baz").msgclass
125
- TestMessage = pool.lookup("TestMessage").msgclass
126
- TestMessage2 = pool.lookup("TestMessage2").msgclass
127
- TestEmbeddedMessageParent = pool.lookup("TestEmbeddedMessageParent").msgclass
128
- TestEmbeddedMessageChild = pool.lookup("TestEmbeddedMessageChild").msgclass
129
- Recursive1 = pool.lookup("Recursive1").msgclass
130
- Recursive2 = pool.lookup("Recursive2").msgclass
131
- TestEnum = pool.lookup("TestEnum").enummodule
132
24
  BadFieldNames = pool.lookup("BadFieldNames").msgclass
133
- MapMessage = pool.lookup("MapMessage").msgclass
134
- MapMessageWireEquiv = pool.lookup("MapMessageWireEquiv").msgclass
135
- MapMessageWireEquiv_entry1 =
136
- pool.lookup("MapMessageWireEquiv_entry1").msgclass
137
- MapMessageWireEquiv_entry2 =
138
- pool.lookup("MapMessageWireEquiv_entry2").msgclass
139
- OneofMessage = pool.lookup("OneofMessage").msgclass
140
25
 
141
26
  # ------------ test cases ---------------
142
27
 
143
28
  class MessageContainerTest < Test::Unit::TestCase
144
-
145
- def test_defaults
146
- m = TestMessage.new
147
- assert m.optional_int32 == 0
148
- assert m.optional_int64 == 0
149
- assert m.optional_uint32 == 0
150
- assert m.optional_uint64 == 0
151
- assert m.optional_bool == false
152
- assert m.optional_float == 0.0
153
- assert m.optional_double == 0.0
154
- assert m.optional_string == ""
155
- assert m.optional_bytes == ""
156
- assert m.optional_msg == nil
157
- assert m.optional_enum == :Default
29
+ # Required by CommonTests module to resolve proto3 proto classes used in tests.
30
+ def proto_module
31
+ ::BasicTest
158
32
  end
33
+ include CommonTests
159
34
 
160
- def test_setters
35
+ def test_has_field
161
36
  m = TestMessage.new
162
- m.optional_int32 = -42
163
- assert m.optional_int32 == -42
164
- m.optional_int64 = -0x1_0000_0000
165
- assert m.optional_int64 == -0x1_0000_0000
166
- m.optional_uint32 = 0x9000_0000
167
- assert m.optional_uint32 == 0x9000_0000
168
- m.optional_uint64 = 0x9000_0000_0000_0000
169
- assert m.optional_uint64 == 0x9000_0000_0000_0000
170
- m.optional_bool = true
171
- assert m.optional_bool == true
172
- m.optional_float = 0.5
173
- assert m.optional_float == 0.5
174
- m.optional_double = 0.5
175
- m.optional_string = "hello"
176
- assert m.optional_string == "hello"
177
- m.optional_string = :hello
178
- assert m.optional_string == "hello"
179
- m.optional_bytes = "world".encode!('ASCII-8BIT')
180
- assert m.optional_bytes == "world"
181
- m.optional_msg = TestMessage2.new(:foo => 42)
182
- assert m.optional_msg == TestMessage2.new(:foo => 42)
183
- m.optional_msg = nil
184
- assert m.optional_msg == nil
185
- m.optional_enum = :C
186
- assert m.optional_enum == :C
187
- m.optional_enum = 'C'
188
- assert m.optional_enum == :C
189
- end
190
-
191
- def test_ctor_args
192
- m = TestMessage.new(:optional_int32 => -42,
193
- :optional_msg => TestMessage2.new,
194
- :optional_enum => :C,
195
- :repeated_string => ["hello", "there", "world"])
196
- assert m.optional_int32 == -42
197
- assert m.optional_msg.class == TestMessage2
198
- assert m.repeated_string.length == 3
199
- assert m.optional_enum == :C
200
- assert m.repeated_string[0] == "hello"
201
- assert m.repeated_string[1] == "there"
202
- assert m.repeated_string[2] == "world"
203
- end
204
-
205
- def test_ctor_string_symbol_args
206
- m = TestMessage.new(:optional_enum => 'C', :repeated_enum => ['A', 'B'])
207
- assert_equal :C, m.optional_enum
208
- assert_equal [:A, :B], m.repeated_enum
209
-
210
- m = TestMessage.new(:optional_string => :foo, :repeated_string => [:foo, :bar])
211
- assert_equal 'foo', m.optional_string
212
- assert_equal ['foo', 'bar'], m.repeated_string
213
- end
214
-
215
- def test_embeddedmsg_hash_init
216
- m = TestEmbeddedMessageParent.new(:child_msg => {sub_child: {optional_int32: 1}},
217
- :number => 2,
218
- :repeated_msg => [{sub_child: {optional_int32: 3}}],
219
- :repeated_number => [10, 20, 30])
220
-
221
- assert_equal 2, m.number
222
- assert_equal [10, 20, 30], m.repeated_number
223
-
224
- assert_not_nil m.child_msg
225
- assert_not_nil m.child_msg.sub_child
226
- assert_equal m.child_msg.sub_child.optional_int32, 1
227
-
228
- assert_not_nil m.repeated_msg
229
- assert_equal 1, m.repeated_msg.length
230
- assert_equal 3, m.repeated_msg.first.sub_child.optional_int32
231
- end
232
-
233
- def test_inspect
234
- m = TestMessage.new(:optional_int32 => -42,
235
- :optional_enum => :A,
236
- :optional_msg => TestMessage2.new,
237
- :repeated_string => ["hello", "there", "world"])
238
- 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: []>'
239
- assert_equal expected, m.inspect
240
- end
241
-
242
- def test_hash
243
- m1 = TestMessage.new(:optional_int32 => 42)
244
- m2 = TestMessage.new(:optional_int32 => 102, repeated_string: ['please', 'work', 'ok?'])
245
- m3 = TestMessage.new(:optional_int32 => 102, repeated_string: ['please', 'work', 'ok?'])
246
- assert m1.hash != 0
247
- assert m2.hash != 0
248
- assert m3.hash != 0
249
- # relying on the randomness here -- if hash function changes and we are
250
- # unlucky enough to get a collision, then change the values above.
251
- assert m1.hash != m2.hash
252
- assert_equal m2.hash, m3.hash
253
- end
254
-
255
- def test_unknown_field_errors
256
- e = assert_raise NoMethodError do
257
- TestMessage.new.hello
258
- end
259
- assert_match(/hello/, e.message)
260
-
261
- e = assert_raise NoMethodError do
262
- TestMessage.new.hello = "world"
263
- end
264
- assert_match(/hello/, e.message)
265
- end
266
-
267
- def test_initialization_map_errors
268
- e = assert_raise ArgumentError do
269
- TestMessage.new(:hello => "world")
270
- end
271
- assert_match(/hello/, e.message)
272
-
273
- e = assert_raise ArgumentError do
274
- MapMessage.new(:map_string_int32 => "hello")
275
- end
276
- assert_equal e.message, "Expected Hash object as initializer value for map field 'map_string_int32'."
277
-
278
- e = assert_raise ArgumentError do
279
- TestMessage.new(:repeated_uint32 => "hello")
280
- end
281
- assert_equal e.message, "Expected array as initializer value for repeated field 'repeated_uint32'."
282
- end
283
-
284
- def test_type_errors
285
- m = TestMessage.new
286
- assert_raise TypeError do
287
- m.optional_int32 = "hello"
288
- end
289
- assert_raise TypeError do
290
- m.optional_string = 42
291
- end
292
- assert_raise TypeError do
293
- m.optional_string = nil
294
- end
295
- assert_raise TypeError do
296
- m.optional_bool = 42
297
- end
298
- assert_raise TypeError do
299
- m.optional_msg = TestMessage.new # expects TestMessage2
300
- end
301
-
302
- assert_raise TypeError do
303
- m.repeated_int32 = [] # needs RepeatedField
37
+ assert !m.has_optional_msg?
38
+ m.optional_msg = TestMessage2.new
39
+ assert m.has_optional_msg?
40
+ assert TestMessage.descriptor.lookup('optional_msg').has?(m)
41
+
42
+ m = OneofMessage.new
43
+ assert !m.has_my_oneof?
44
+ m.a = "foo"
45
+ assert m.has_my_oneof?
46
+ assert_raise NoMethodError do
47
+ m.has_a?
304
48
  end
305
-
306
- assert_raise TypeError do
307
- m.repeated_int32.push "hello"
308
- end
309
-
310
- assert_raise TypeError do
311
- m.repeated_msg.push TestMessage.new
49
+ assert_raise ArgumentError do
50
+ OneofMessage.descriptor.lookup('a').has?(m)
312
51
  end
313
- end
314
52
 
315
- def test_string_encoding
316
53
  m = TestMessage.new
317
-
318
- # Assigning a normal (ASCII or UTF8) string to a bytes field, or
319
- # ASCII-8BIT to a string field will convert to the proper encoding.
320
- m.optional_bytes = "Test string ASCII".encode!('ASCII')
321
- assert m.optional_bytes.frozen?
322
- assert_equal Encoding::ASCII_8BIT, m.optional_bytes.encoding
323
- assert_equal "Test string ASCII", m.optional_bytes
324
-
325
- assert_raise Encoding::UndefinedConversionError do
326
- m.optional_bytes = "Test string UTF-8 \u0100".encode!('UTF-8')
54
+ assert_raise NoMethodError do
55
+ m.has_optional_int32?
327
56
  end
328
-
329
- assert_raise Encoding::UndefinedConversionError do
330
- m.optional_string = ["FFFF"].pack('H*')
331
- end
332
-
333
- # "Ordinary" use case.
334
- m.optional_bytes = ["FFFF"].pack('H*')
335
- m.optional_string = "\u0100"
336
-
337
- # strings are immutable so we can't do this, but serialize should catch it.
338
- m.optional_string = "asdf".encode!('UTF-8')
339
- # Ruby 2.5 changed to raise FrozenError. However, assert_raise don't
340
- # accept subclass. Don't specify type here.
341
- assert_raise do
342
- m.optional_string.encode!('ASCII-8BIT')
343
- end
344
- end
345
-
346
- def test_rptfield_int32
347
- l = Google::Protobuf::RepeatedField.new(:int32)
348
- assert l.count == 0
349
- l = Google::Protobuf::RepeatedField.new(:int32, [1, 2, 3])
350
- assert l.count == 3
351
- assert_equal [1, 2, 3], l
352
- assert_equal l, [1, 2, 3]
353
- l.push 4
354
- assert l == [1, 2, 3, 4]
355
- dst_list = []
356
- l.each { |val| dst_list.push val }
357
- assert dst_list == [1, 2, 3, 4]
358
- assert l.to_a == [1, 2, 3, 4]
359
- assert l[0] == 1
360
- assert l[3] == 4
361
- l[0] = 5
362
- assert l == [5, 2, 3, 4]
363
-
364
- l2 = l.dup
365
- assert l == l2
366
- assert l.object_id != l2.object_id
367
- l2.push 6
368
- assert l.count == 4
369
- assert l2.count == 5
370
-
371
- assert l.inspect == '[5, 2, 3, 4]'
372
-
373
- l.concat([7, 8, 9])
374
- assert l == [5, 2, 3, 4, 7, 8, 9]
375
- assert l.pop == 9
376
- assert l == [5, 2, 3, 4, 7, 8]
377
-
378
- assert_raise TypeError do
379
- m = TestMessage.new
380
- l.push m
381
- end
382
-
383
- m = TestMessage.new
384
- m.repeated_int32 = l
385
- assert m.repeated_int32 == [5, 2, 3, 4, 7, 8]
386
- assert m.repeated_int32.object_id == l.object_id
387
- l.push 42
388
- assert m.repeated_int32.pop == 42
389
-
390
- l3 = l + l.dup
391
- assert l3.count == l.count * 2
392
- l.count.times do |i|
393
- assert l3[i] == l[i]
394
- assert l3[l.count + i] == l[i]
57
+ assert_raise ArgumentError do
58
+ TestMessage.descriptor.lookup('optional_int32').has?(m)
395
59
  end
396
60
 
397
- l.clear
398
- assert l.count == 0
399
- l += [1, 2, 3, 4]
400
- l.replace([5, 6, 7, 8])
401
- assert l == [5, 6, 7, 8]
402
-
403
- l4 = Google::Protobuf::RepeatedField.new(:int32)
404
- l4[5] = 42
405
- assert l4 == [0, 0, 0, 0, 0, 42]
406
-
407
- l4 << 100
408
- assert l4 == [0, 0, 0, 0, 0, 42, 100]
409
- l4 << 101 << 102
410
- assert l4 == [0, 0, 0, 0, 0, 42, 100, 101, 102]
411
- end
412
-
413
- def test_parent_rptfield
414
- #make sure we set the RepeatedField and can add to it
415
- m = TestMessage.new
416
- assert m.repeated_string == []
417
- m.repeated_string << 'ok'
418
- m.repeated_string.push('ok2')
419
- assert m.repeated_string == ['ok', 'ok2']
420
- m.repeated_string += ['ok3']
421
- assert m.repeated_string == ['ok', 'ok2', 'ok3']
422
- end
423
-
424
- def test_rptfield_msg
425
- l = Google::Protobuf::RepeatedField.new(:message, TestMessage)
426
- l.push TestMessage.new
427
- assert l.count == 1
428
- assert_raise TypeError do
429
- l.push TestMessage2.new
61
+ assert_raise NoMethodError do
62
+ m.has_optional_string?
430
63
  end
431
- assert_raise TypeError do
432
- l.push 42
64
+ assert_raise ArgumentError do
65
+ TestMessage.descriptor.lookup('optional_string').has?(m)
433
66
  end
434
67
 
435
- l2 = l.dup
436
- assert l2[0] == l[0]
437
- assert l2[0].object_id == l[0].object_id
438
-
439
- l2 = Google::Protobuf.deep_copy(l)
440
- assert l2[0] == l[0]
441
- assert l2[0].object_id != l[0].object_id
442
-
443
- l3 = l + l2
444
- assert l3.count == 2
445
- assert l3[0] == l[0]
446
- assert l3[1] == l2[0]
447
- l3[0].optional_int32 = 1000
448
- assert l[0].optional_int32 == 1000
449
-
450
- new_msg = TestMessage.new(:optional_int32 => 200)
451
- l4 = l + [new_msg]
452
- assert l4.count == 2
453
- new_msg.optional_int32 = 1000
454
- assert l4[1].optional_int32 == 1000
455
- end
456
-
457
- def test_rptfield_enum
458
- l = Google::Protobuf::RepeatedField.new(:enum, TestEnum)
459
- l.push :A
460
- l.push :B
461
- l.push :C
462
- assert l.count == 3
463
- assert_raise RangeError do
464
- l.push :D
68
+ assert_raise NoMethodError do
69
+ m.has_optional_bool?
465
70
  end
466
- assert l[0] == :A
467
-
468
- l.push 4
469
- assert l[3] == 4
470
- end
471
-
472
- def test_rptfield_initialize
473
71
  assert_raise ArgumentError do
474
- l = Google::Protobuf::RepeatedField.new
72
+ TestMessage.descriptor.lookup('optional_bool').has?(m)
475
73
  end
476
- assert_raise ArgumentError do
477
- l = Google::Protobuf::RepeatedField.new(:message)
478
- end
479
- assert_raise ArgumentError do
480
- l = Google::Protobuf::RepeatedField.new([1, 2, 3])
74
+
75
+ assert_raise NoMethodError do
76
+ m.has_repeated_msg?
481
77
  end
482
78
  assert_raise ArgumentError do
483
- l = Google::Protobuf::RepeatedField.new(:message, [TestMessage2.new])
79
+ TestMessage.descriptor.lookup('repeated_msg').has?(m)
484
80
  end
485
81
  end
486
82
 
487
- def test_rptfield_array_ducktyping
488
- l = Google::Protobuf::RepeatedField.new(:int32)
489
- length_methods = %w(count length size)
490
- length_methods.each do |lm|
491
- assert l.send(lm) == 0
492
- end
493
- # out of bounds returns a nil
494
- assert l[0] == nil
495
- assert l[1] == nil
496
- assert l[-1] == nil
497
- l.push 4
498
- length_methods.each do |lm|
499
- assert l.send(lm) == 1
500
- end
501
- assert l[0] == 4
502
- assert l[1] == nil
503
- assert l[-1] == 4
504
- assert l[-2] == nil
505
-
506
- l.push 2
507
- length_methods.each do |lm|
508
- assert l.send(lm) == 2
509
- end
510
- assert l[0] == 4
511
- assert l[1] == 2
512
- assert l[2] == nil
513
- assert l[-1] == 2
514
- assert l[-2] == 4
515
- assert l[-3] == nil
83
+ def test_set_clear_defaults
84
+ m = TestMessage.new
516
85
 
517
- #adding out of scope will backfill with empty objects
518
- end
86
+ m.optional_int32 = -42
87
+ assert_equal -42, m.optional_int32
88
+ m.clear_optional_int32
89
+ assert_equal 0, m.optional_int32
519
90
 
520
- def test_map_basic
521
- # allowed key types:
522
- # :int32, :int64, :uint32, :uint64, :bool, :string, :bytes.
91
+ m.optional_int32 = 50
92
+ assert_equal 50, m.optional_int32
93
+ TestMessage.descriptor.lookup('optional_int32').clear(m)
94
+ assert_equal 0, m.optional_int32
523
95
 
524
- m = Google::Protobuf::Map.new(:string, :int32)
525
- m["asdf"] = 1
526
- assert m["asdf"] == 1
527
- m["jkl;"] = 42
528
- assert m == { "jkl;" => 42, "asdf" => 1 }
529
- assert m.has_key?("asdf")
530
- assert !m.has_key?("qwerty")
531
- assert m.length == 2
96
+ m.optional_string = "foo bar"
97
+ assert_equal "foo bar", m.optional_string
98
+ m.clear_optional_string
99
+ assert_equal "", m.optional_string
532
100
 
533
- m2 = m.dup
534
- assert_equal m, m2
535
- assert m.hash != 0
536
- assert_equal m.hash, m2.hash
101
+ m.optional_string = "foo"
102
+ assert_equal "foo", m.optional_string
103
+ TestMessage.descriptor.lookup('optional_string').clear(m)
104
+ assert_equal "", m.optional_string
537
105
 
538
- collected = {}
539
- m.each { |k,v| collected[v] = k }
540
- assert collected == { 42 => "jkl;", 1 => "asdf" }
106
+ m.optional_msg = TestMessage2.new(:foo => 42)
107
+ assert_equal TestMessage2.new(:foo => 42), m.optional_msg
108
+ assert m.has_optional_msg?
109
+ m.clear_optional_msg
110
+ assert_equal nil, m.optional_msg
111
+ assert !m.has_optional_msg?
541
112
 
542
- assert m.delete("asdf") == 1
543
- assert !m.has_key?("asdf")
544
- assert m["asdf"] == nil
545
- assert !m.has_key?("asdf")
113
+ m.optional_msg = TestMessage2.new(:foo => 42)
114
+ assert_equal TestMessage2.new(:foo => 42), m.optional_msg
115
+ TestMessage.descriptor.lookup('optional_msg').clear(m)
116
+ assert_equal nil, m.optional_msg
546
117
 
547
- # We only assert on inspect value when there is one map entry because the
548
- # order in which elements appear is unspecified (depends on the internal
549
- # hash function). We don't want a brittle test.
550
- assert m.inspect == "{\"jkl;\"=>42}"
118
+ m.repeated_int32.push(1)
119
+ assert_equal [1], m.repeated_int32
120
+ m.clear_repeated_int32
121
+ assert_equal [], m.repeated_int32
551
122
 
552
- assert m.keys == ["jkl;"]
553
- assert m.values == [42]
123
+ m.repeated_int32.push(1)
124
+ assert_equal [1], m.repeated_int32
125
+ TestMessage.descriptor.lookup('repeated_int32').clear(m)
126
+ assert_equal [], m.repeated_int32
554
127
 
555
- m.clear
556
- assert m.length == 0
557
- assert m == {}
128
+ m = OneofMessage.new
129
+ m.a = "foo"
130
+ assert_equal "foo", m.a
131
+ assert m.has_my_oneof?
132
+ m.clear_a
133
+ assert !m.has_my_oneof?
558
134
 
559
- assert_raise TypeError do
560
- m[1] = 1
561
- end
562
- assert_raise RangeError do
563
- m["asdf"] = 0x1_0000_0000
564
- end
565
- end
135
+ m.a = "foobar"
136
+ assert m.has_my_oneof?
137
+ m.clear_my_oneof
138
+ assert !m.has_my_oneof?
566
139
 
567
- def test_map_ctor
568
- m = Google::Protobuf::Map.new(:string, :int32,
569
- {"a" => 1, "b" => 2, "c" => 3})
570
- assert m == {"a" => 1, "c" => 3, "b" => 2}
140
+ m.a = "bar"
141
+ assert_equal "bar", m.a
142
+ assert m.has_my_oneof?
143
+ OneofMessage.descriptor.lookup('a').clear(m)
144
+ assert !m.has_my_oneof?
571
145
  end
572
146
 
573
- def test_map_keytypes
574
- m = Google::Protobuf::Map.new(:int32, :int32)
575
- m[1] = 42
576
- m[-1] = 42
577
- assert_raise RangeError do
578
- m[0x8000_0000] = 1
579
- end
580
- assert_raise TypeError do
581
- m["asdf"] = 1
582
- end
583
-
584
- m = Google::Protobuf::Map.new(:int64, :int32)
585
- m[0x1000_0000_0000_0000] = 1
586
- assert_raise RangeError do
587
- m[0x1_0000_0000_0000_0000] = 1
588
- end
589
- assert_raise TypeError do
590
- m["asdf"] = 1
591
- end
592
-
593
- m = Google::Protobuf::Map.new(:uint32, :int32)
594
- m[0x8000_0000] = 1
595
- assert_raise RangeError do
596
- m[0x1_0000_0000] = 1
597
- end
598
- assert_raise RangeError do
599
- m[-1] = 1
600
- end
601
-
602
- m = Google::Protobuf::Map.new(:uint64, :int32)
603
- m[0x8000_0000_0000_0000] = 1
604
- assert_raise RangeError do
605
- m[0x1_0000_0000_0000_0000] = 1
606
- end
607
- assert_raise RangeError do
608
- m[-1] = 1
609
- end
610
-
611
- m = Google::Protobuf::Map.new(:bool, :int32)
612
- m[true] = 1
613
- m[false] = 2
614
- assert_raise TypeError do
615
- m[1] = 1
616
- end
617
- assert_raise TypeError do
618
- m["asdf"] = 1
619
- end
620
-
621
- m = Google::Protobuf::Map.new(:string, :int32)
622
- m["asdf"] = 1
623
- assert_raise TypeError do
624
- m[1] = 1
625
- end
626
- assert_raise Encoding::UndefinedConversionError do
627
- bytestring = ["FFFF"].pack("H*")
628
- m[bytestring] = 1
629
- end
630
147
 
631
- m = Google::Protobuf::Map.new(:bytes, :int32)
632
- bytestring = ["FFFF"].pack("H*")
633
- m[bytestring] = 1
634
- # Allowed -- we will automatically convert to ASCII-8BIT.
635
- m["asdf"] = 1
636
- assert_raise TypeError do
637
- m[1] = 1
148
+ def test_initialization_map_errors
149
+ e = assert_raise ArgumentError do
150
+ TestMessage.new(:hello => "world")
638
151
  end
639
- end
152
+ assert_match(/hello/, e.message)
640
153
 
641
- def test_map_msg_enum_valuetypes
642
- m = Google::Protobuf::Map.new(:string, :message, TestMessage)
643
- m["asdf"] = TestMessage.new
644
- assert_raise TypeError do
645
- m["jkl;"] = TestMessage2.new
154
+ e = assert_raise ArgumentError do
155
+ MapMessage.new(:map_string_int32 => "hello")
646
156
  end
157
+ assert_equal e.message, "Expected Hash object as initializer value for map field 'map_string_int32' (given String)."
647
158
 
648
- m = Google::Protobuf::Map.new(
649
- :string, :message, TestMessage,
650
- { "a" => TestMessage.new(:optional_int32 => 42),
651
- "b" => TestMessage.new(:optional_int32 => 84) })
652
- assert m.length == 2
653
- assert m.values.map{|msg| msg.optional_int32}.sort == [42, 84]
654
-
655
- m = Google::Protobuf::Map.new(:string, :enum, TestEnum,
656
- { "x" => :A, "y" => :B, "z" => :C })
657
- assert m.length == 3
658
- assert m["z"] == :C
659
- m["z"] = 2
660
- assert m["z"] == :B
661
- m["z"] = 4
662
- assert m["z"] == 4
663
- assert_raise RangeError do
664
- m["z"] = :Z
665
- end
666
- assert_raise RangeError do
667
- m["z"] = "z"
159
+ e = assert_raise ArgumentError do
160
+ TestMessage.new(:repeated_uint32 => "hello")
668
161
  end
669
- end
670
-
671
- def test_map_dup_deep_copy
672
- m = Google::Protobuf::Map.new(
673
- :string, :message, TestMessage,
674
- { "a" => TestMessage.new(:optional_int32 => 42),
675
- "b" => TestMessage.new(:optional_int32 => 84) })
676
-
677
- m2 = m.dup
678
- assert m == m2
679
- assert m.object_id != m2.object_id
680
- assert m["a"].object_id == m2["a"].object_id
681
- assert m["b"].object_id == m2["b"].object_id
682
-
683
- m2 = Google::Protobuf.deep_copy(m)
684
- assert m == m2
685
- assert m.object_id != m2.object_id
686
- assert m["a"].object_id != m2["a"].object_id
687
- assert m["b"].object_id != m2["b"].object_id
162
+ assert_equal e.message, "Expected array as initializer value for repeated field 'repeated_uint32' (given String)."
688
163
  end
689
164
 
690
165
  def test_map_field
@@ -695,10 +170,12 @@ module BasicTest
695
170
  m = MapMessage.new(
696
171
  :map_string_int32 => {"a" => 1, "b" => 2},
697
172
  :map_string_msg => {"a" => TestMessage2.new(:foo => 1),
698
- "b" => TestMessage2.new(:foo => 2)})
173
+ "b" => TestMessage2.new(:foo => 2)},
174
+ :map_string_enum => {"a" => :A, "b" => :B})
699
175
  assert m.map_string_int32.keys.sort == ["a", "b"]
700
176
  assert m.map_string_int32["a"] == 1
701
177
  assert m.map_string_msg["b"].foo == 2
178
+ assert m.map_string_enum["a"] == :A
702
179
 
703
180
  m.map_string_int32["c"] = 3
704
181
  assert m.map_string_int32["c"] == 3
@@ -708,17 +185,17 @@ module BasicTest
708
185
  m.map_string_msg.delete("c")
709
186
  assert m.map_string_msg == { "a" => TestMessage2.new(:foo => 1) }
710
187
 
711
- assert_raise TypeError do
188
+ assert_raise Google::Protobuf::TypeError do
712
189
  m.map_string_msg["e"] = TestMessage.new # wrong value type
713
190
  end
714
191
  # ensure nothing was added by the above
715
192
  assert m.map_string_msg == { "a" => TestMessage2.new(:foo => 1) }
716
193
 
717
194
  m.map_string_int32 = Google::Protobuf::Map.new(:string, :int32)
718
- assert_raise TypeError do
195
+ assert_raise Google::Protobuf::TypeError do
719
196
  m.map_string_int32 = Google::Protobuf::Map.new(:string, :int64)
720
197
  end
721
- assert_raise TypeError do
198
+ assert_raise Google::Protobuf::TypeError do
722
199
  m.map_string_int32 = {}
723
200
  end
724
201
 
@@ -727,6 +204,16 @@ module BasicTest
727
204
  end
728
205
  end
729
206
 
207
+ def test_map_inspect
208
+ m = MapMessage.new(
209
+ :map_string_int32 => {"a" => 1, "b" => 2},
210
+ :map_string_msg => {"a" => TestMessage2.new(:foo => 1),
211
+ "b" => TestMessage2.new(:foo => 2)},
212
+ :map_string_enum => {"a" => :A, "b" => :B})
213
+ expected = "<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}>"
214
+ assert_equal expected, m.inspect
215
+ end
216
+
730
217
  def test_map_corruption
731
218
  # This pattern led to a crash in a previous version of upb/protobuf.
732
219
  m = MapMessage.new(map_string_int32: { "aaa" => 1 })
@@ -753,7 +240,8 @@ module BasicTest
753
240
  m = MapMessage.new(
754
241
  :map_string_int32 => {"a" => 1, "b" => 2},
755
242
  :map_string_msg => {"a" => TestMessage2.new(:foo => 1),
756
- "b" => TestMessage2.new(:foo => 2)})
243
+ "b" => TestMessage2.new(:foo => 2)},
244
+ :map_string_enum => {"a" => :A, "b" => :B})
757
245
  m2 = MapMessage.decode(MapMessage.encode(m))
758
246
  assert m == m2
759
247
 
@@ -770,209 +258,17 @@ module BasicTest
770
258
  "b" => TestMessage2.new(:foo => 2)}
771
259
  end
772
260
 
773
- def test_oneof_descriptors
774
- d = OneofMessage.descriptor
775
- o = d.lookup_oneof("my_oneof")
776
- assert o != nil
777
- assert o.class == Google::Protobuf::OneofDescriptor
778
- assert o.name == "my_oneof"
779
- oneof_count = 0
780
- d.each_oneof{ |oneof|
781
- oneof_count += 1
782
- assert oneof == o
783
- }
784
- assert oneof_count == 1
785
- assert o.count == 4
786
- field_names = o.map{|f| f.name}.sort
787
- assert field_names == ["a", "b", "c", "d"]
788
- end
789
-
790
- def test_oneof
791
- d = OneofMessage.new
792
- assert d.a == ""
793
- assert d.b == 0
794
- assert d.c == nil
795
- assert d.d == :Default
796
- assert d.my_oneof == nil
797
-
798
- d.a = "hi"
799
- assert d.a == "hi"
800
- assert d.b == 0
801
- assert d.c == nil
802
- assert d.d == :Default
803
- assert d.my_oneof == :a
804
-
805
- d.b = 42
806
- assert d.a == ""
807
- assert d.b == 42
808
- assert d.c == nil
809
- assert d.d == :Default
810
- assert d.my_oneof == :b
811
-
812
- d.c = TestMessage2.new(:foo => 100)
813
- assert d.a == ""
814
- assert d.b == 0
815
- assert d.c.foo == 100
816
- assert d.d == :Default
817
- assert d.my_oneof == :c
818
-
819
- d.d = :C
820
- assert d.a == ""
821
- assert d.b == 0
822
- assert d.c == nil
823
- assert d.d == :C
824
- assert d.my_oneof == :d
825
-
826
- d2 = OneofMessage.decode(OneofMessage.encode(d))
827
- assert d2 == d
828
-
829
- encoded_field_a = OneofMessage.encode(OneofMessage.new(:a => "string"))
830
- encoded_field_b = OneofMessage.encode(OneofMessage.new(:b => 1000))
831
- encoded_field_c = OneofMessage.encode(
832
- OneofMessage.new(:c => TestMessage2.new(:foo => 1)))
833
- encoded_field_d = OneofMessage.encode(OneofMessage.new(:d => :B))
834
-
835
- d3 = OneofMessage.decode(
836
- encoded_field_c + encoded_field_a + encoded_field_d)
837
- assert d3.a == ""
838
- assert d3.b == 0
839
- assert d3.c == nil
840
- assert d3.d == :B
841
-
842
- d4 = OneofMessage.decode(
843
- encoded_field_c + encoded_field_a + encoded_field_d +
844
- encoded_field_c)
845
- assert d4.a == ""
846
- assert d4.b == 0
847
- assert d4.c.foo == 1
848
- assert d4.d == :Default
261
+ def test_protobuf_decode_json_ignore_unknown_fields
262
+ m = TestMessage.decode_json({
263
+ optional_string: "foo",
264
+ not_in_message: "some_value"
265
+ }.to_json, { ignore_unknown_fields: true })
849
266
 
850
- d5 = OneofMessage.new(:a => "hello")
851
- assert d5.a == "hello"
852
- d5.a = nil
853
- assert d5.a == ""
854
- assert OneofMessage.encode(d5) == ''
855
- assert d5.my_oneof == nil
856
- end
857
-
858
- def test_enum_field
859
- m = TestMessage.new
860
- assert m.optional_enum == :Default
861
- m.optional_enum = :A
862
- assert m.optional_enum == :A
863
- assert_raise RangeError do
864
- m.optional_enum = :ASDF
267
+ assert_equal m.optional_string, "foo"
268
+ e = assert_raise Google::Protobuf::ParseError do
269
+ TestMessage.decode_json({ not_in_message: "some_value" }.to_json)
865
270
  end
866
- m.optional_enum = 1
867
- assert m.optional_enum == :A
868
- m.optional_enum = 100
869
- assert m.optional_enum == 100
870
- end
871
-
872
- def test_dup
873
- m = TestMessage.new
874
- m.optional_string = "hello"
875
- m.optional_int32 = 42
876
- tm1 = TestMessage2.new(:foo => 100)
877
- tm2 = TestMessage2.new(:foo => 200)
878
- m.repeated_msg.push tm1
879
- assert m.repeated_msg[-1] == tm1
880
- m.repeated_msg.push tm2
881
- assert m.repeated_msg[-1] == tm2
882
- m2 = m.dup
883
- assert m == m2
884
- m.optional_int32 += 1
885
- assert m != m2
886
- assert m.repeated_msg[0] == m2.repeated_msg[0]
887
- assert m.repeated_msg[0].object_id == m2.repeated_msg[0].object_id
888
- end
889
-
890
- def test_deep_copy
891
- m = TestMessage.new(:optional_int32 => 42,
892
- :repeated_msg => [TestMessage2.new(:foo => 100)])
893
- m2 = Google::Protobuf.deep_copy(m)
894
- assert m == m2
895
- assert m.repeated_msg == m2.repeated_msg
896
- assert m.repeated_msg.object_id != m2.repeated_msg.object_id
897
- assert m.repeated_msg[0].object_id != m2.repeated_msg[0].object_id
898
- end
899
-
900
- def test_eq
901
- m = TestMessage.new(:optional_int32 => 42,
902
- :repeated_int32 => [1, 2, 3])
903
- m2 = TestMessage.new(:optional_int32 => 43,
904
- :repeated_int32 => [1, 2, 3])
905
- assert m != m2
906
- end
907
-
908
- def test_enum_lookup
909
- assert TestEnum::A == 1
910
- assert TestEnum::B == 2
911
- assert TestEnum::C == 3
912
-
913
- assert TestEnum::lookup(1) == :A
914
- assert TestEnum::lookup(2) == :B
915
- assert TestEnum::lookup(3) == :C
916
-
917
- assert TestEnum::resolve(:A) == 1
918
- assert TestEnum::resolve(:B) == 2
919
- assert TestEnum::resolve(:C) == 3
920
- end
921
-
922
- def test_parse_serialize
923
- m = TestMessage.new(:optional_int32 => 42,
924
- :optional_string => "hello world",
925
- :optional_enum => :B,
926
- :repeated_string => ["a", "b", "c"],
927
- :repeated_int32 => [42, 43, 44],
928
- :repeated_enum => [:A, :B, :C, 100],
929
- :repeated_msg => [TestMessage2.new(:foo => 1),
930
- TestMessage2.new(:foo => 2)])
931
- data = TestMessage.encode m
932
- m2 = TestMessage.decode data
933
- assert m == m2
934
-
935
- data = Google::Protobuf.encode m
936
- m2 = Google::Protobuf.decode(TestMessage, data)
937
- assert m == m2
938
- end
939
-
940
- def test_encode_decode_helpers
941
- m = TestMessage.new(:optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
942
- assert_equal 'foo', m.optional_string
943
- assert_equal ['bar1', 'bar2'], m.repeated_string
944
-
945
- json = m.to_json
946
- m2 = TestMessage.decode_json(json)
947
- assert_equal 'foo', m2.optional_string
948
- assert_equal ['bar1', 'bar2'], m2.repeated_string
949
- if RUBY_PLATFORM != "java"
950
- assert m2.optional_string.frozen?
951
- assert m2.repeated_string[0].frozen?
952
- end
953
-
954
- proto = m.to_proto
955
- m2 = TestMessage.decode(proto)
956
- assert_equal 'foo', m2.optional_string
957
- assert_equal ['bar1', 'bar2'], m2.repeated_string
958
- end
959
-
960
- def test_protobuf_encode_decode_helpers
961
- m = TestMessage.new(:optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
962
- encoded_msg = Google::Protobuf.encode(m)
963
- assert_equal m.to_proto, encoded_msg
964
-
965
- decoded_msg = Google::Protobuf.decode(TestMessage, encoded_msg)
966
- assert_equal TestMessage.decode(m.to_proto), decoded_msg
967
- end
968
-
969
- def test_protobuf_encode_decode_json_helpers
970
- m = TestMessage.new(:optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
971
- encoded_msg = Google::Protobuf.encode_json(m)
972
- assert_equal m.to_json, encoded_msg
973
-
974
- decoded_msg = Google::Protobuf.decode_json(TestMessage, encoded_msg)
975
- assert_equal TestMessage.decode_json(m.to_json), decoded_msg
271
+ assert_match(/No such field: not_in_message/, e.message)
976
272
  end
977
273
 
978
274
  def test_to_h
@@ -1006,392 +302,41 @@ module BasicTest
1006
302
  m = MapMessage.new(
1007
303
  :map_string_int32 => {"a" => 1, "b" => 2},
1008
304
  :map_string_msg => {"a" => TestMessage2.new(:foo => 1),
1009
- "b" => TestMessage2.new(:foo => 2)})
305
+ "b" => TestMessage2.new(:foo => 2)},
306
+ :map_string_enum => {"a" => :A, "b" => :B})
1010
307
  expected_result = {
1011
308
  :map_string_int32 => {"a" => 1, "b" => 2},
1012
- :map_string_msg => {"a" => {:foo => 1}, "b" => {:foo => 2}}
309
+ :map_string_msg => {"a" => {:foo => 1}, "b" => {:foo => 2}},
310
+ :map_string_enum => {"a" => :A, "b" => :B}
1013
311
  }
1014
312
  assert_equal expected_result, m.to_h
1015
313
  end
1016
314
 
1017
315
 
1018
- def test_def_errors
1019
- s = Google::Protobuf::DescriptorPool.new
1020
- assert_raise TypeError do
1021
- s.build do
1022
- # enum with no default (integer value 0)
1023
- add_enum "MyEnum" do
1024
- value :A, 1
1025
- end
1026
- end
1027
- end
1028
- assert_raise TypeError do
1029
- s.build do
1030
- # message with required field (unsupported in proto3)
1031
- add_message "MyMessage" do
1032
- required :foo, :int32, 1
1033
- end
1034
- end
1035
- end
1036
- end
1037
-
1038
- def test_corecursive
1039
- # just be sure that we can instantiate types with corecursive field-type
1040
- # references.
1041
- m = Recursive1.new(:foo => Recursive2.new(:foo => Recursive1.new))
1042
- assert Recursive1.descriptor.lookup("foo").subtype ==
1043
- Recursive2.descriptor
1044
- assert Recursive2.descriptor.lookup("foo").subtype ==
1045
- Recursive1.descriptor
1046
-
1047
- serialized = Recursive1.encode(m)
1048
- m2 = Recursive1.decode(serialized)
1049
- assert m == m2
1050
- end
1051
-
1052
- def test_serialize_cycle
1053
- m = Recursive1.new(:foo => Recursive2.new)
1054
- m.foo.foo = m
1055
- assert_raise RuntimeError do
1056
- serialized = Recursive1.encode(m)
1057
- end
1058
- end
1059
-
1060
- def test_bad_field_names
1061
- m = BadFieldNames.new(:dup => 1, :class => 2)
1062
- m2 = m.dup
1063
- assert m == m2
1064
- assert m['dup'] == 1
1065
- assert m['class'] == 2
1066
- m['dup'] = 3
1067
- assert m['dup'] == 3
1068
- m['a.b'] = 4
1069
- assert m['a.b'] == 4
1070
- end
1071
-
1072
- def test_int_ranges
1073
- m = TestMessage.new
1074
-
1075
- m.optional_int32 = 0
1076
- m.optional_int32 = -0x8000_0000
1077
- m.optional_int32 = +0x7fff_ffff
1078
- m.optional_int32 = 1.0
1079
- m.optional_int32 = -1.0
1080
- m.optional_int32 = 2e9
1081
- assert_raise RangeError do
1082
- m.optional_int32 = -0x8000_0001
1083
- end
1084
- assert_raise RangeError do
1085
- m.optional_int32 = +0x8000_0000
1086
- end
1087
- assert_raise RangeError do
1088
- m.optional_int32 = +0x1000_0000_0000_0000_0000_0000 # force Bignum
1089
- end
1090
- assert_raise RangeError do
1091
- m.optional_int32 = 1e12
1092
- end
1093
- assert_raise RangeError do
1094
- m.optional_int32 = 1.5
1095
- end
1096
-
1097
- m.optional_uint32 = 0
1098
- m.optional_uint32 = +0xffff_ffff
1099
- m.optional_uint32 = 1.0
1100
- m.optional_uint32 = 4e9
1101
- assert_raise RangeError do
1102
- m.optional_uint32 = -1
1103
- end
1104
- assert_raise RangeError do
1105
- m.optional_uint32 = -1.5
1106
- end
1107
- assert_raise RangeError do
1108
- m.optional_uint32 = -1.5e12
1109
- end
1110
- assert_raise RangeError do
1111
- m.optional_uint32 = -0x1000_0000_0000_0000
1112
- end
1113
- assert_raise RangeError do
1114
- m.optional_uint32 = +0x1_0000_0000
1115
- end
1116
- assert_raise RangeError do
1117
- m.optional_uint32 = +0x1000_0000_0000_0000_0000_0000 # force Bignum
1118
- end
1119
- assert_raise RangeError do
1120
- m.optional_uint32 = 1e12
1121
- end
1122
- assert_raise RangeError do
1123
- m.optional_uint32 = 1.5
1124
- end
1125
-
1126
- m.optional_int64 = 0
1127
- m.optional_int64 = -0x8000_0000_0000_0000
1128
- m.optional_int64 = +0x7fff_ffff_ffff_ffff
1129
- m.optional_int64 = 1.0
1130
- m.optional_int64 = -1.0
1131
- m.optional_int64 = 8e18
1132
- m.optional_int64 = -8e18
1133
- assert_raise RangeError do
1134
- m.optional_int64 = -0x8000_0000_0000_0001
1135
- end
1136
- assert_raise RangeError do
1137
- m.optional_int64 = +0x8000_0000_0000_0000
1138
- end
1139
- assert_raise RangeError do
1140
- m.optional_int64 = +0x1000_0000_0000_0000_0000_0000 # force Bignum
1141
- end
1142
- assert_raise RangeError do
1143
- m.optional_int64 = 1e50
1144
- end
1145
- assert_raise RangeError do
1146
- m.optional_int64 = 1.5
1147
- end
1148
-
1149
- m.optional_uint64 = 0
1150
- m.optional_uint64 = +0xffff_ffff_ffff_ffff
1151
- m.optional_uint64 = 1.0
1152
- m.optional_uint64 = 16e18
1153
- assert_raise RangeError do
1154
- m.optional_uint64 = -1
1155
- end
1156
- assert_raise RangeError do
1157
- m.optional_uint64 = -1.5
1158
- end
1159
- assert_raise RangeError do
1160
- m.optional_uint64 = -1.5e12
1161
- end
1162
- assert_raise RangeError do
1163
- m.optional_uint64 = -0x1_0000_0000_0000_0000
1164
- end
1165
- assert_raise RangeError do
1166
- m.optional_uint64 = +0x1_0000_0000_0000_0000
1167
- end
1168
- assert_raise RangeError do
1169
- m.optional_uint64 = +0x1000_0000_0000_0000_0000_0000 # force Bignum
1170
- end
1171
- assert_raise RangeError do
1172
- m.optional_uint64 = 1e50
1173
- end
1174
- assert_raise RangeError do
1175
- m.optional_uint64 = 1.5
1176
- end
1177
- end
1178
-
1179
- def test_stress_test
1180
- m = TestMessage.new
1181
- m.optional_int32 = 42
1182
- m.optional_int64 = 0x100000000
1183
- m.optional_string = "hello world"
1184
- 10.times do m.repeated_msg.push TestMessage2.new(:foo => 42) end
1185
- 10.times do m.repeated_string.push "hello world" end
1186
-
1187
- data = TestMessage.encode(m)
1188
-
1189
- l = 0
1190
- 10_000.times do
1191
- m = TestMessage.decode(data)
1192
- data_new = TestMessage.encode(m)
1193
- assert data_new == data
1194
- data = data_new
1195
- end
1196
- end
1197
-
1198
- def test_reflection
1199
- m = TestMessage.new(:optional_int32 => 1234)
1200
- msgdef = m.class.descriptor
1201
- assert msgdef.class == Google::Protobuf::Descriptor
1202
- assert msgdef.any? {|field| field.name == "optional_int32"}
1203
- optional_int32 = msgdef.lookup "optional_int32"
1204
- assert optional_int32.class == Google::Protobuf::FieldDescriptor
1205
- assert optional_int32 != nil
1206
- assert optional_int32.name == "optional_int32"
1207
- assert optional_int32.type == :int32
1208
- optional_int32.set(m, 5678)
1209
- assert m.optional_int32 == 5678
1210
- m.optional_int32 = 1000
1211
- assert optional_int32.get(m) == 1000
1212
-
1213
- optional_msg = msgdef.lookup "optional_msg"
1214
- assert optional_msg.subtype == TestMessage2.descriptor
1215
-
1216
- optional_msg.set(m, optional_msg.subtype.msgclass.new)
1217
-
1218
- assert msgdef.msgclass == TestMessage
1219
-
1220
- optional_enum = msgdef.lookup "optional_enum"
1221
- assert optional_enum.subtype == TestEnum.descriptor
1222
- assert optional_enum.subtype.class == Google::Protobuf::EnumDescriptor
1223
- optional_enum.subtype.each do |k, v|
1224
- # set with integer, check resolution to symbolic name
1225
- optional_enum.set(m, v)
1226
- assert optional_enum.get(m) == k
1227
- end
1228
- end
1229
-
1230
- def test_json
1231
- # TODO: Fix JSON in JRuby version.
1232
- return if RUBY_PLATFORM == "java"
1233
- m = TestMessage.new(:optional_int32 => 1234,
1234
- :optional_int64 => -0x1_0000_0000,
1235
- :optional_uint32 => 0x8000_0000,
1236
- :optional_uint64 => 0xffff_ffff_ffff_ffff,
1237
- :optional_bool => true,
1238
- :optional_float => 1.0,
1239
- :optional_double => -1e100,
1240
- :optional_string => "Test string",
1241
- :optional_bytes => ["FFFFFFFF"].pack('H*'),
1242
- :optional_msg => TestMessage2.new(:foo => 42),
1243
- :repeated_int32 => [1, 2, 3, 4],
1244
- :repeated_string => ["a", "b", "c"],
1245
- :repeated_bool => [true, false, true, false],
1246
- :repeated_msg => [TestMessage2.new(:foo => 1),
1247
- TestMessage2.new(:foo => 2)])
1248
-
1249
- json_text = TestMessage.encode_json(m)
1250
- m2 = TestMessage.decode_json(json_text)
1251
- puts m.inspect
1252
- puts m2.inspect
1253
- assert m == m2
1254
-
1255
- # Crash case from GitHub issue 283.
1256
- bar = Bar.new(msg: "bar")
1257
- baz1 = Baz.new(msg: "baz")
1258
- baz2 = Baz.new(msg: "quux")
1259
- Foo.encode_json(Foo.new)
1260
- Foo.encode_json(Foo.new(bar: bar))
1261
- Foo.encode_json(Foo.new(bar: bar, baz: [baz1, baz2]))
1262
- end
1263
-
1264
- def test_json_emit_defaults
1265
- # TODO: Fix JSON in JRuby version.
1266
- return if RUBY_PLATFORM == "java"
1267
- m = TestMessage.new
1268
-
1269
- expected = {
1270
- optionalInt32: 0,
1271
- optionalInt64: 0,
1272
- optionalUint32: 0,
1273
- optionalUint64: 0,
1274
- optionalBool: false,
1275
- optionalFloat: 0,
1276
- optionalDouble: 0,
1277
- optionalString: "",
1278
- optionalBytes: "",
1279
- optionalEnum: "Default",
1280
- repeatedInt32: [],
1281
- repeatedInt64: [],
1282
- repeatedUint32: [],
1283
- repeatedUint64: [],
1284
- repeatedBool: [],
1285
- repeatedFloat: [],
1286
- repeatedDouble: [],
1287
- repeatedString: [],
1288
- repeatedBytes: [],
1289
- repeatedMsg: [],
1290
- repeatedEnum: []
1291
- }
1292
-
1293
- actual = TestMessage.encode_json(m, :emit_defaults => true)
1294
-
1295
- assert JSON.parse(actual, :symbolize_names => true) == expected
1296
- end
1297
-
1298
- def test_json_emit_defaults_submsg
1299
- # TODO: Fix JSON in JRuby version.
1300
- return if RUBY_PLATFORM == "java"
1301
- m = TestMessage.new(optional_msg: TestMessage2.new)
1302
-
1303
- expected = {
1304
- optionalInt32: 0,
1305
- optionalInt64: 0,
1306
- optionalUint32: 0,
1307
- optionalUint64: 0,
1308
- optionalBool: false,
1309
- optionalFloat: 0,
1310
- optionalDouble: 0,
1311
- optionalString: "",
1312
- optionalBytes: "",
1313
- optionalMsg: {foo: 0},
1314
- optionalEnum: "Default",
1315
- repeatedInt32: [],
1316
- repeatedInt64: [],
1317
- repeatedUint32: [],
1318
- repeatedUint64: [],
1319
- repeatedBool: [],
1320
- repeatedFloat: [],
1321
- repeatedDouble: [],
1322
- repeatedString: [],
1323
- repeatedBytes: [],
1324
- repeatedMsg: [],
1325
- repeatedEnum: []
1326
- }
1327
-
1328
- actual = TestMessage.encode_json(m, :emit_defaults => true)
1329
-
1330
- assert JSON.parse(actual, :symbolize_names => true) == expected
1331
- end
1332
-
1333
- def test_json_emit_defaults_repeated_submsg
1334
- # TODO: Fix JSON in JRuby version.
1335
- return if RUBY_PLATFORM == "java"
1336
- m = TestMessage.new(repeated_msg: [TestMessage2.new])
1337
-
1338
- expected = {
1339
- optionalInt32: 0,
1340
- optionalInt64: 0,
1341
- optionalUint32: 0,
1342
- optionalUint64: 0,
1343
- optionalBool: false,
1344
- optionalFloat: 0,
1345
- optionalDouble: 0,
1346
- optionalString: "",
1347
- optionalBytes: "",
1348
- optionalEnum: "Default",
1349
- repeatedInt32: [],
1350
- repeatedInt64: [],
1351
- repeatedUint32: [],
1352
- repeatedUint64: [],
1353
- repeatedBool: [],
1354
- repeatedFloat: [],
1355
- repeatedDouble: [],
1356
- repeatedString: [],
1357
- repeatedBytes: [],
1358
- repeatedMsg: [{foo: 0}],
1359
- repeatedEnum: []
1360
- }
1361
-
1362
- actual = TestMessage.encode_json(m, :emit_defaults => true)
1363
-
1364
- assert JSON.parse(actual, :symbolize_names => true) == expected
1365
- end
1366
-
1367
316
  def test_json_maps
1368
317
  # TODO: Fix JSON in JRuby version.
1369
318
  return if RUBY_PLATFORM == "java"
1370
319
  m = MapMessage.new(:map_string_int32 => {"a" => 1})
1371
- expected = {mapStringInt32: {a: 1}, mapStringMsg: {}}
1372
- expected_preserve = {map_string_int32: {a: 1}, map_string_msg: {}}
1373
- assert JSON.parse(MapMessage.encode_json(m), :symbolize_names => true) == expected
320
+ expected = {mapStringInt32: {a: 1}, mapStringMsg: {}, mapStringEnum: {}}
321
+ expected_preserve = {map_string_int32: {a: 1}, map_string_msg: {}, map_string_enum: {}}
322
+ assert_equal JSON.parse(MapMessage.encode_json(m), :symbolize_names => true), expected
1374
323
 
1375
324
  json = MapMessage.encode_json(m, :preserve_proto_fieldnames => true)
1376
- assert JSON.parse(json, :symbolize_names => true) == expected_preserve
325
+ assert_equal JSON.parse(json, :symbolize_names => true), expected_preserve
1377
326
 
1378
327
  m2 = MapMessage.decode_json(MapMessage.encode_json(m))
1379
- assert m == m2
328
+ assert_equal m, m2
1380
329
  end
1381
330
 
1382
331
  def test_json_maps_emit_defaults_submsg
1383
332
  # TODO: Fix JSON in JRuby version.
1384
333
  return if RUBY_PLATFORM == "java"
1385
334
  m = MapMessage.new(:map_string_msg => {"a" => TestMessage2.new})
1386
- expected = {mapStringInt32: {}, mapStringMsg: {a: {foo: 0}}}
335
+ expected = {mapStringInt32: {}, mapStringMsg: {a: {foo: 0}}, mapStringEnum: {}}
1387
336
 
1388
337
  actual = MapMessage.encode_json(m, :emit_defaults => true)
1389
338
 
1390
- assert JSON.parse(actual, :symbolize_names => true) == expected
1391
- end
1392
-
1393
- def test_comparison_with_arbitrary_object
1394
- assert MapMessage.new != nil
339
+ assert_equal JSON.parse(actual, :symbolize_names => true), expected
1395
340
  end
1396
341
 
1397
342
  def test_respond_to
@@ -1401,5 +346,42 @@ module BasicTest
1401
346
  assert msg.respond_to?(:map_string_int32)
1402
347
  assert !msg.respond_to?(:bacon)
1403
348
  end
349
+
350
+ def test_file_descriptor
351
+ file_descriptor = TestMessage.descriptor.file_descriptor
352
+ assert nil != file_descriptor
353
+ assert_equal "tests/basic_test.proto", file_descriptor.name
354
+ assert_equal :proto3, file_descriptor.syntax
355
+
356
+ file_descriptor = TestEnum.descriptor.file_descriptor
357
+ assert nil != file_descriptor
358
+ assert_equal "tests/basic_test.proto", file_descriptor.name
359
+ assert_equal :proto3, file_descriptor.syntax
360
+
361
+ file_descriptor = BadFieldNames.descriptor.file_descriptor
362
+ assert nil != file_descriptor
363
+ assert_equal nil, file_descriptor.name
364
+ assert_equal :proto3, file_descriptor.syntax
365
+ end
366
+
367
+ # Ruby 2.5 changed to raise FrozenError instead of RuntimeError
368
+ FrozenErrorType = Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.5') ? RuntimeError : FrozenError
369
+
370
+ def test_map_freeze
371
+ m = proto_module::MapMessage.new
372
+ m.map_string_int32['a'] = 5
373
+ m.map_string_msg['b'] = proto_module::TestMessage2.new
374
+
375
+ m.map_string_int32.freeze
376
+ m.map_string_msg.freeze
377
+
378
+ assert m.map_string_int32.frozen?
379
+ assert m.map_string_msg.frozen?
380
+
381
+ assert_raise(FrozenErrorType) { m.map_string_int32['foo'] = 1 }
382
+ assert_raise(FrozenErrorType) { m.map_string_msg['bar'] = proto_module::TestMessage2.new }
383
+ assert_raise(FrozenErrorType) { m.map_string_int32.delete('a') }
384
+ assert_raise(FrozenErrorType) { m.map_string_int32.clear }
385
+ end
1404
386
  end
1405
387
  end