google-protobuf 3.4.0.2 → 3.19.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


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

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