google-protobuf 3.2.0 → 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.

@@ -4,32 +4,34 @@
4
4
  require 'google/protobuf'
5
5
 
6
6
  Google::Protobuf::DescriptorPool.generated_pool.build do
7
- add_message "google.protobuf.DoubleValue" do
8
- optional :value, :double, 1
9
- end
10
- add_message "google.protobuf.FloatValue" do
11
- optional :value, :float, 1
12
- end
13
- add_message "google.protobuf.Int64Value" do
14
- optional :value, :int64, 1
15
- end
16
- add_message "google.protobuf.UInt64Value" do
17
- optional :value, :uint64, 1
18
- end
19
- add_message "google.protobuf.Int32Value" do
20
- optional :value, :int32, 1
21
- end
22
- add_message "google.protobuf.UInt32Value" do
23
- optional :value, :uint32, 1
24
- end
25
- add_message "google.protobuf.BoolValue" do
26
- optional :value, :bool, 1
27
- end
28
- add_message "google.protobuf.StringValue" do
29
- optional :value, :string, 1
30
- end
31
- add_message "google.protobuf.BytesValue" do
32
- optional :value, :bytes, 1
7
+ add_file("google/protobuf/wrappers.proto", :syntax => :proto3) do
8
+ add_message "google.protobuf.DoubleValue" do
9
+ optional :value, :double, 1
10
+ end
11
+ add_message "google.protobuf.FloatValue" do
12
+ optional :value, :float, 1
13
+ end
14
+ add_message "google.protobuf.Int64Value" do
15
+ optional :value, :int64, 1
16
+ end
17
+ add_message "google.protobuf.UInt64Value" do
18
+ optional :value, :uint64, 1
19
+ end
20
+ add_message "google.protobuf.Int32Value" do
21
+ optional :value, :int32, 1
22
+ end
23
+ add_message "google.protobuf.UInt32Value" do
24
+ optional :value, :uint32, 1
25
+ end
26
+ add_message "google.protobuf.BoolValue" do
27
+ optional :value, :bool, 1
28
+ end
29
+ add_message "google.protobuf.StringValue" do
30
+ optional :value, :string, 1
31
+ end
32
+ add_message "google.protobuf.BytesValue" do
33
+ optional :value, :bytes, 1
34
+ end
33
35
  end
34
36
  end
35
37
 
@@ -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,152 @@ 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
20
  optional :"a.b", :int32, 3
71
21
  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
- end
98
22
  end
99
23
 
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
24
  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
25
 
117
26
  # ------------ test cases ---------------
118
27
 
119
28
  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
29
+ # Required by CommonTests module to resolve proto3 proto classes used in tests.
30
+ def proto_module
31
+ ::BasicTest
134
32
  end
33
+ include CommonTests
135
34
 
136
- def test_setters
35
+ def test_has_field
137
36
  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
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?
200
48
  end
201
- assert_match(/hello/, e.message)
202
-
203
- e = assert_raise NoMethodError do
204
- TestMessage.new.hello = "world"
205
- end
206
- assert_match(/hello/, e.message)
207
- end
208
-
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)
214
-
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'."
219
-
220
- e = assert_raise ArgumentError do
221
- TestMessage.new(:repeated_uint32 => "hello")
222
- end
223
- assert_equal e.message, "Expected array as initializer value for repeated field 'repeated_uint32'."
224
- end
225
-
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
243
-
244
- assert_raise TypeError do
245
- m.repeated_int32 = [] # needs RepeatedField
246
- end
247
-
248
- assert_raise TypeError do
249
- m.repeated_int32.push "hello"
250
- end
251
-
252
- assert_raise TypeError do
253
- m.repeated_msg.push TestMessage.new
49
+ assert_raise ArgumentError do
50
+ OneofMessage.descriptor.lookup('a').has?(m)
254
51
  end
255
- end
256
52
 
257
- def test_string_encoding
258
53
  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')
269
- end
270
-
271
- assert_raise Encoding::UndefinedConversionError do
272
- m.optional_string = ["FFFF"].pack('H*')
54
+ assert_raise NoMethodError do
55
+ m.has_optional_int32?
273
56
  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')
57
+ assert_raise ArgumentError do
58
+ TestMessage.descriptor.lookup('optional_int32').has?(m)
283
59
  end
284
- end
285
-
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
60
 
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
61
+ assert_raise NoMethodError do
62
+ m.has_optional_string?
321
63
  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]
335
- end
336
-
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
- 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
370
- end
371
- assert_raise TypeError do
372
- l.push 42
373
- 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
- end
396
-
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
64
+ assert_raise ArgumentError do
65
+ TestMessage.descriptor.lookup('optional_string').has?(m)
405
66
  end
406
- assert l[0] == :A
407
-
408
- l.push 4
409
- assert l[3] == 4
410
- end
411
67
 
412
- def test_rptfield_initialize
413
- assert_raise ArgumentError do
414
- l = Google::Protobuf::RepeatedField.new
68
+ assert_raise NoMethodError do
69
+ m.has_optional_bool?
415
70
  end
416
71
  assert_raise ArgumentError do
417
- l = Google::Protobuf::RepeatedField.new(:message)
72
+ TestMessage.descriptor.lookup('optional_bool').has?(m)
418
73
  end
419
- assert_raise ArgumentError do
420
- l = Google::Protobuf::RepeatedField.new([1, 2, 3])
74
+
75
+ assert_raise NoMethodError do
76
+ m.has_repeated_msg?
421
77
  end
422
78
  assert_raise ArgumentError do
423
- l = Google::Protobuf::RepeatedField.new(:message, [TestMessage2.new])
79
+ TestMessage.descriptor.lookup('repeated_msg').has?(m)
424
80
  end
425
81
  end
426
82
 
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
83
+ def test_set_clear_defaults
84
+ m = TestMessage.new
456
85
 
457
- #adding out of scope will backfill with empty objects
458
- 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
459
90
 
460
- def test_map_basic
461
- # allowed key types:
462
- # :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
463
95
 
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
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
472
100
 
473
- m2 = m.dup
474
- assert_equal m, m2
475
- assert m.hash != 0
476
- 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
477
105
 
478
- collected = {}
479
- m.each { |k,v| collected[v] = k }
480
- 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?
481
112
 
482
- assert m.delete("asdf") == 1
483
- assert !m.has_key?("asdf")
484
- assert m["asdf"] == nil
485
- 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
486
117
 
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}"
118
+ m.repeated_int32.push(1)
119
+ assert_equal [1], m.repeated_int32
120
+ m.clear_repeated_int32
121
+ assert_equal [], m.repeated_int32
491
122
 
492
- assert m.keys == ["jkl;"]
493
- 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
494
127
 
495
- m.clear
496
- assert m.length == 0
497
- 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?
498
134
 
499
- assert_raise TypeError do
500
- m[1] = 1
501
- end
502
- assert_raise RangeError do
503
- m["asdf"] = 0x1_0000_0000
504
- end
505
- end
135
+ m.a = "foobar"
136
+ assert m.has_my_oneof?
137
+ m.clear_my_oneof
138
+ assert !m.has_my_oneof?
506
139
 
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}
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?
511
145
  end
512
146
 
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
523
-
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
532
147
 
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
541
-
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
550
-
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
560
-
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
570
-
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
148
+ def test_initialization_map_errors
149
+ e = assert_raise ArgumentError do
150
+ TestMessage.new(:hello => "world")
578
151
  end
579
- end
152
+ assert_match(/hello/, e.message)
580
153
 
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
154
+ e = assert_raise ArgumentError do
155
+ MapMessage.new(:map_string_int32 => "hello")
586
156
  end
157
+ assert_equal e.message, "Expected Hash object as initializer value for map field 'map_string_int32' (given String)."
587
158
 
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"
159
+ e = assert_raise ArgumentError do
160
+ TestMessage.new(:repeated_uint32 => "hello")
608
161
  end
609
- end
610
-
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
162
+ assert_equal e.message, "Expected array as initializer value for repeated field 'repeated_uint32' (given String)."
628
163
  end
629
164
 
630
165
  def test_map_field
@@ -635,10 +170,12 @@ module BasicTest
635
170
  m = MapMessage.new(
636
171
  :map_string_int32 => {"a" => 1, "b" => 2},
637
172
  :map_string_msg => {"a" => TestMessage2.new(:foo => 1),
638
- "b" => TestMessage2.new(:foo => 2)})
173
+ "b" => TestMessage2.new(:foo => 2)},
174
+ :map_string_enum => {"a" => :A, "b" => :B})
639
175
  assert m.map_string_int32.keys.sort == ["a", "b"]
640
176
  assert m.map_string_int32["a"] == 1
641
177
  assert m.map_string_msg["b"].foo == 2
178
+ assert m.map_string_enum["a"] == :A
642
179
 
643
180
  m.map_string_int32["c"] = 3
644
181
  assert m.map_string_int32["c"] == 3
@@ -648,17 +185,17 @@ module BasicTest
648
185
  m.map_string_msg.delete("c")
649
186
  assert m.map_string_msg == { "a" => TestMessage2.new(:foo => 1) }
650
187
 
651
- assert_raise TypeError do
188
+ assert_raise Google::Protobuf::TypeError do
652
189
  m.map_string_msg["e"] = TestMessage.new # wrong value type
653
190
  end
654
191
  # ensure nothing was added by the above
655
192
  assert m.map_string_msg == { "a" => TestMessage2.new(:foo => 1) }
656
193
 
657
194
  m.map_string_int32 = Google::Protobuf::Map.new(:string, :int32)
658
- assert_raise TypeError do
195
+ assert_raise Google::Protobuf::TypeError do
659
196
  m.map_string_int32 = Google::Protobuf::Map.new(:string, :int64)
660
197
  end
661
- assert_raise TypeError do
198
+ assert_raise Google::Protobuf::TypeError do
662
199
  m.map_string_int32 = {}
663
200
  end
664
201
 
@@ -667,6 +204,16 @@ module BasicTest
667
204
  end
668
205
  end
669
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
+
670
217
  def test_map_corruption
671
218
  # This pattern led to a crash in a previous version of upb/protobuf.
672
219
  m = MapMessage.new(map_string_int32: { "aaa" => 1 })
@@ -674,11 +221,27 @@ module BasicTest
674
221
  m.map_string_int32['aaa'] = 3
675
222
  end
676
223
 
224
+ def test_concurrent_decoding
225
+ o = Outer.new
226
+ o.items[0] = Inner.new
227
+ raw = Outer.encode(o)
228
+
229
+ thds = 2.times.map do
230
+ Thread.new do
231
+ 100000.times do
232
+ assert_equal o, Outer.decode(raw)
233
+ end
234
+ end
235
+ end
236
+ thds.map(&:join)
237
+ end
238
+
677
239
  def test_map_encode_decode
678
240
  m = MapMessage.new(
679
241
  :map_string_int32 => {"a" => 1, "b" => 2},
680
242
  :map_string_msg => {"a" => TestMessage2.new(:foo => 1),
681
- "b" => TestMessage2.new(:foo => 2)})
243
+ "b" => TestMessage2.new(:foo => 2)},
244
+ :map_string_enum => {"a" => :A, "b" => :B})
682
245
  m2 = MapMessage.decode(MapMessage.encode(m))
683
246
  assert m == m2
684
247
 
@@ -695,213 +258,21 @@ module BasicTest
695
258
  "b" => TestMessage2.new(:foo => 2)}
696
259
  end
697
260
 
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
782
-
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
790
- end
791
- m.optional_enum = 1
792
- assert m.optional_enum == :A
793
- m.optional_enum = 100
794
- assert m.optional_enum == 100
795
- end
796
-
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
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 })
869
266
 
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?
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)
877
270
  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
271
+ assert_match(/No such field: not_in_message/, e.message)
901
272
  end
902
273
 
903
274
  def test_to_h
904
- m = TestMessage.new(:optional_bool => true, :optional_double => -10.100001, :optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
275
+ m = TestMessage.new(:optional_bool => true, :optional_double => -10.100001, :optional_string => 'foo', :repeated_string => ['bar1', 'bar2'], :repeated_msg => [TestMessage2.new(:foo => 100)])
905
276
  expected_result = {
906
277
  :optional_bool=>true,
907
278
  :optional_bytes=>"",
@@ -921,276 +292,51 @@ module BasicTest
921
292
  :repeated_float=>[],
922
293
  :repeated_int32=>[],
923
294
  :repeated_int64=>[],
924
- :repeated_msg=>[],
295
+ :repeated_msg=>[{:foo => 100}],
925
296
  :repeated_string=>["bar1", "bar2"],
926
297
  :repeated_uint32=>[],
927
298
  :repeated_uint64=>[]
928
299
  }
929
300
  assert_equal expected_result, m.to_h
930
- end
931
-
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
301
 
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
985
- end
986
-
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
-
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
1093
-
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
1112
-
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
302
+ m = MapMessage.new(
303
+ :map_string_int32 => {"a" => 1, "b" => 2},
304
+ :map_string_msg => {"a" => TestMessage2.new(:foo => 1),
305
+ "b" => TestMessage2.new(:foo => 2)},
306
+ :map_string_enum => {"a" => :A, "b" => :B})
307
+ expected_result = {
308
+ :map_string_int32 => {"a" => 1, "b" => 2},
309
+ :map_string_msg => {"a" => {:foo => 1}, "b" => {:foo => 2}},
310
+ :map_string_enum => {"a" => :A, "b" => :B}
311
+ }
312
+ assert_equal expected_result, m.to_h
1143
313
  end
1144
314
 
1145
- def test_json
1146
- # TODO: Fix JSON in JRuby version.
1147
- 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
1167
-
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]))
1175
- end
1176
315
 
1177
316
  def test_json_maps
1178
317
  # TODO: Fix JSON in JRuby version.
1179
318
  return if RUBY_PLATFORM == "java"
1180
319
  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
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
1184
323
 
1185
324
  json = MapMessage.encode_json(m, :preserve_proto_fieldnames => true)
1186
- assert json == expected_preserve
325
+ assert_equal JSON.parse(json, :symbolize_names => true), expected_preserve
1187
326
 
1188
327
  m2 = MapMessage.decode_json(MapMessage.encode_json(m))
1189
- assert m == m2
328
+ assert_equal m, m2
1190
329
  end
1191
330
 
1192
- def test_comparison_with_arbitrary_object
1193
- assert MapMessage.new != nil
331
+ def test_json_maps_emit_defaults_submsg
332
+ # TODO: Fix JSON in JRuby version.
333
+ return if RUBY_PLATFORM == "java"
334
+ m = MapMessage.new(:map_string_msg => {"a" => TestMessage2.new})
335
+ expected = {mapStringInt32: {}, mapStringMsg: {a: {foo: 0}}, mapStringEnum: {}}
336
+
337
+ actual = MapMessage.encode_json(m, :emit_defaults => true)
338
+
339
+ assert_equal JSON.parse(actual, :symbolize_names => true), expected
1194
340
  end
1195
341
 
1196
342
  def test_respond_to
@@ -1200,5 +346,42 @@ module BasicTest
1200
346
  assert msg.respond_to?(:map_string_int32)
1201
347
  assert !msg.respond_to?(:bacon)
1202
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
1203
386
  end
1204
387
  end