google-protobuf 3.0.0.alpha.1.0

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.

@@ -0,0 +1,31 @@
1
+ # Protocol Buffers - Google's data interchange format
2
+ # Copyright 2008 Google Inc. All rights reserved.
3
+ # https://developers.google.com/protocol-buffers/
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are
7
+ # met:
8
+ #
9
+ # * Redistributions of source code must retain the above copyright
10
+ # notice, this list of conditions and the following disclaimer.
11
+ # * Redistributions in binary form must reproduce the above
12
+ # copyright notice, this list of conditions and the following disclaimer
13
+ # in the documentation and/or other materials provided with the
14
+ # distribution.
15
+ # * Neither the name of Google Inc. nor the names of its
16
+ # contributors may be used to endorse or promote products derived from
17
+ # this software without specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ require 'google/protobuf_c'
data/tests/basic.rb ADDED
@@ -0,0 +1,633 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'google/protobuf'
4
+ require 'test/unit'
5
+
6
+ # ------------- generated code --------------
7
+
8
+ module BasicTest
9
+ pool = Google::Protobuf::DescriptorPool.new
10
+ pool.build do
11
+ add_message "TestMessage" do
12
+ optional :optional_int32, :int32, 1
13
+ optional :optional_int64, :int64, 2
14
+ optional :optional_uint32, :uint32, 3
15
+ optional :optional_uint64, :uint64, 4
16
+ optional :optional_bool, :bool, 5
17
+ optional :optional_float, :float, 6
18
+ optional :optional_double, :double, 7
19
+ optional :optional_string, :string, 8
20
+ optional :optional_bytes, :bytes, 9
21
+ optional :optional_msg, :message, 10, "TestMessage2"
22
+ optional :optional_enum, :enum, 11, "TestEnum"
23
+
24
+ repeated :repeated_int32, :int32, 12
25
+ repeated :repeated_int64, :int64, 13
26
+ repeated :repeated_uint32, :uint32, 14
27
+ repeated :repeated_uint64, :uint64, 15
28
+ repeated :repeated_bool, :bool, 16
29
+ repeated :repeated_float, :float, 17
30
+ repeated :repeated_double, :double, 18
31
+ repeated :repeated_string, :string, 19
32
+ repeated :repeated_bytes, :bytes, 20
33
+ repeated :repeated_msg, :message, 21, "TestMessage2"
34
+ repeated :repeated_enum, :enum, 22, "TestEnum"
35
+ end
36
+ add_message "TestMessage2" do
37
+ optional :foo, :int32, 1
38
+ end
39
+ add_message "Recursive1" do
40
+ optional :foo, :message, 1, "Recursive2"
41
+ end
42
+ add_message "Recursive2" do
43
+ optional :foo, :message, 1, "Recursive1"
44
+ end
45
+ add_enum "TestEnum" do
46
+ value :Default, 0
47
+ value :A, 1
48
+ value :B, 2
49
+ value :C, 3
50
+ end
51
+ add_message "BadFieldNames" do
52
+ optional :dup, :int32, 1
53
+ optional :class, :int32, 2
54
+ optional :"a.b", :int32, 3
55
+ end
56
+ end
57
+
58
+ TestMessage = pool.lookup("TestMessage").msgclass
59
+ TestMessage2 = pool.lookup("TestMessage2").msgclass
60
+ Recursive1 = pool.lookup("Recursive1").msgclass
61
+ Recursive2 = pool.lookup("Recursive2").msgclass
62
+ TestEnum = pool.lookup("TestEnum").enummodule
63
+ BadFieldNames = pool.lookup("BadFieldNames").msgclass
64
+
65
+ # ------------ test cases ---------------
66
+
67
+ class MessageContainerTest < Test::Unit::TestCase
68
+
69
+ def test_defaults
70
+ m = TestMessage.new
71
+ assert m.optional_int32 == 0
72
+ assert m.optional_int64 == 0
73
+ assert m.optional_uint32 == 0
74
+ assert m.optional_uint64 == 0
75
+ assert m.optional_bool == false
76
+ assert m.optional_float == 0.0
77
+ assert m.optional_double == 0.0
78
+ assert m.optional_string == ""
79
+ assert m.optional_bytes == ""
80
+ assert m.optional_msg == nil
81
+ assert m.optional_enum == :Default
82
+ end
83
+
84
+ def test_setters
85
+ m = TestMessage.new
86
+ m.optional_int32 = -42
87
+ assert m.optional_int32 == -42
88
+ m.optional_int64 = -0x1_0000_0000
89
+ assert m.optional_int64 == -0x1_0000_0000
90
+ m.optional_uint32 = 0x9000_0000
91
+ assert m.optional_uint32 == 0x9000_0000
92
+ m.optional_uint64 = 0x9000_0000_0000_0000
93
+ assert m.optional_uint64 == 0x9000_0000_0000_0000
94
+ m.optional_bool = true
95
+ assert m.optional_bool == true
96
+ m.optional_float = 0.5
97
+ assert m.optional_float == 0.5
98
+ m.optional_double = 0.5
99
+ m.optional_string = "hello"
100
+ assert m.optional_string == "hello"
101
+ m.optional_bytes = "world".encode!('ASCII-8BIT')
102
+ assert m.optional_bytes == "world"
103
+ m.optional_msg = TestMessage2.new(:foo => 42)
104
+ assert m.optional_msg == TestMessage2.new(:foo => 42)
105
+ end
106
+
107
+ def test_ctor_args
108
+ m = TestMessage.new(:optional_int32 => -42,
109
+ :optional_msg => TestMessage2.new,
110
+ :optional_enum => :C,
111
+ :repeated_string => ["hello", "there", "world"])
112
+ assert m.optional_int32 == -42
113
+ assert m.optional_msg.class == TestMessage2
114
+ assert m.repeated_string.length == 3
115
+ assert m.optional_enum == :C
116
+ assert m.repeated_string[0] == "hello"
117
+ assert m.repeated_string[1] == "there"
118
+ assert m.repeated_string[2] == "world"
119
+ end
120
+
121
+ def test_inspect
122
+ m = TestMessage.new(:optional_int32 => -42,
123
+ :optional_enum => :A,
124
+ :optional_msg => TestMessage2.new,
125
+ :repeated_string => ["hello", "there", "world"])
126
+ 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: []>'
127
+ assert m.inspect == expected
128
+ end
129
+
130
+ def test_hash
131
+ m1 = TestMessage.new(:optional_int32 => 42)
132
+ m2 = TestMessage.new(:optional_int32 => 102)
133
+ assert m1.hash != 0
134
+ assert m2.hash != 0
135
+ # relying on the randomness here -- if hash function changes and we are
136
+ # unlucky enough to get a collision, then change the values above.
137
+ assert m1.hash != m2.hash
138
+ end
139
+
140
+ def test_type_errors
141
+ m = TestMessage.new
142
+ assert_raise TypeError do
143
+ m.optional_int32 = "hello"
144
+ end
145
+ assert_raise TypeError do
146
+ m.optional_string = 42
147
+ end
148
+ assert_raise TypeError do
149
+ m.optional_string = nil
150
+ end
151
+ assert_raise TypeError do
152
+ m.optional_bool = 42
153
+ end
154
+ assert_raise TypeError do
155
+ m.optional_msg = TestMessage.new # expects TestMessage2
156
+ end
157
+
158
+ assert_raise TypeError do
159
+ m.repeated_int32 = [] # needs RepeatedField
160
+ end
161
+
162
+ assert_raise TypeError do
163
+ m.repeated_int32.push "hello"
164
+ end
165
+
166
+ assert_raise TypeError do
167
+ m.repeated_msg.push TestMessage.new
168
+ end
169
+ end
170
+
171
+ def test_string_encoding
172
+ m = TestMessage.new
173
+
174
+ # Assigning a normal (ASCII or UTF8) string to a bytes field, or
175
+ # ASCII-8BIT to a string field, raises an error.
176
+ assert_raise TypeError do
177
+ m.optional_bytes = "Test string ASCII".encode!('ASCII')
178
+ end
179
+ assert_raise TypeError do
180
+ m.optional_bytes = "Test string UTF-8 \u0100".encode!('UTF-8')
181
+ end
182
+ assert_raise TypeError do
183
+ m.optional_string = ["FFFF"].pack('H*')
184
+ end
185
+
186
+ # "Ordinary" use case.
187
+ m.optional_bytes = ["FFFF"].pack('H*')
188
+ m.optional_string = "\u0100"
189
+
190
+ # strings are mutable so we can do this, but serialize should catch it.
191
+ m.optional_string = "asdf".encode!('UTF-8')
192
+ m.optional_string.encode!('ASCII-8BIT')
193
+ assert_raise TypeError do
194
+ data = TestMessage.encode(m)
195
+ end
196
+ end
197
+
198
+ def test_rptfield_int32
199
+ l = Google::Protobuf::RepeatedField.new(:int32)
200
+ assert l.count == 0
201
+ l = Google::Protobuf::RepeatedField.new(:int32, [1, 2, 3])
202
+ assert l.count == 3
203
+ assert l == [1, 2, 3]
204
+ l.push 4
205
+ assert l == [1, 2, 3, 4]
206
+ dst_list = []
207
+ l.each { |val| dst_list.push val }
208
+ assert dst_list == [1, 2, 3, 4]
209
+ assert l.to_a == [1, 2, 3, 4]
210
+ assert l[0] == 1
211
+ assert l[3] == 4
212
+ l[0] = 5
213
+ assert l == [5, 2, 3, 4]
214
+
215
+ l2 = l.dup
216
+ assert l == l2
217
+ assert l.object_id != l2.object_id
218
+ l2.push 6
219
+ assert l.count == 4
220
+ assert l2.count == 5
221
+
222
+ assert l.inspect == '[5, 2, 3, 4]'
223
+
224
+ l.insert(7, 8, 9)
225
+ assert l == [5, 2, 3, 4, 7, 8, 9]
226
+ assert l.pop == 9
227
+ assert l == [5, 2, 3, 4, 7, 8]
228
+
229
+ assert_raise TypeError do
230
+ m = TestMessage.new
231
+ l.push m
232
+ end
233
+
234
+ m = TestMessage.new
235
+ m.repeated_int32 = l
236
+ assert m.repeated_int32 == [5, 2, 3, 4, 7, 8]
237
+ assert m.repeated_int32.object_id == l.object_id
238
+ l.push 42
239
+ assert m.repeated_int32.pop == 42
240
+
241
+ l3 = l + l.dup
242
+ assert l3.count == l.count * 2
243
+ l.count.times do |i|
244
+ assert l3[i] == l[i]
245
+ assert l3[l.count + i] == l[i]
246
+ end
247
+
248
+ l.clear
249
+ assert l.count == 0
250
+ l += [1, 2, 3, 4]
251
+ l.replace([5, 6, 7, 8])
252
+ assert l == [5, 6, 7, 8]
253
+
254
+ l4 = Google::Protobuf::RepeatedField.new(:int32)
255
+ l4[5] = 42
256
+ assert l4 == [0, 0, 0, 0, 0, 42]
257
+
258
+ l4 << 100
259
+ assert l4 == [0, 0, 0, 0, 0, 42, 100]
260
+ l4 << 101 << 102
261
+ assert l4 == [0, 0, 0, 0, 0, 42, 100, 101, 102]
262
+ end
263
+
264
+ def test_rptfield_msg
265
+ l = Google::Protobuf::RepeatedField.new(:message, TestMessage)
266
+ l.push TestMessage.new
267
+ assert l.count == 1
268
+ assert_raise TypeError do
269
+ l.push TestMessage2.new
270
+ end
271
+ assert_raise TypeError do
272
+ l.push 42
273
+ end
274
+
275
+ l2 = l.dup
276
+ assert l2[0] == l[0]
277
+ assert l2[0].object_id == l[0].object_id
278
+
279
+ l2 = Google::Protobuf.deep_copy(l)
280
+ assert l2[0] == l[0]
281
+ assert l2[0].object_id != l[0].object_id
282
+
283
+ l3 = l + l2
284
+ assert l3.count == 2
285
+ assert l3[0] == l[0]
286
+ assert l3[1] == l2[0]
287
+ l3[0].optional_int32 = 1000
288
+ assert l[0].optional_int32 == 1000
289
+
290
+ new_msg = TestMessage.new(:optional_int32 => 200)
291
+ l4 = l + [new_msg]
292
+ assert l4.count == 2
293
+ new_msg.optional_int32 = 1000
294
+ assert l4[1].optional_int32 == 1000
295
+ end
296
+
297
+ def test_rptfield_enum
298
+ l = Google::Protobuf::RepeatedField.new(:enum, TestEnum)
299
+ l.push :A
300
+ l.push :B
301
+ l.push :C
302
+ assert l.count == 3
303
+ assert_raise NameError do
304
+ l.push :D
305
+ end
306
+ assert l[0] == :A
307
+
308
+ l.push 4
309
+ assert l[3] == 4
310
+ end
311
+
312
+ def test_rptfield_initialize
313
+ assert_raise ArgumentError do
314
+ l = Google::Protobuf::RepeatedField.new
315
+ end
316
+ assert_raise ArgumentError do
317
+ l = Google::Protobuf::RepeatedField.new(:message)
318
+ end
319
+ assert_raise ArgumentError do
320
+ l = Google::Protobuf::RepeatedField.new([1, 2, 3])
321
+ end
322
+ assert_raise ArgumentError do
323
+ l = Google::Protobuf::RepeatedField.new(:message, [TestMessage2.new])
324
+ end
325
+ end
326
+
327
+ def test_enum_field
328
+ m = TestMessage.new
329
+ assert m.optional_enum == :Default
330
+ m.optional_enum = :A
331
+ assert m.optional_enum == :A
332
+ assert_raise NameError do
333
+ m.optional_enum = :ASDF
334
+ end
335
+ m.optional_enum = 1
336
+ assert m.optional_enum == :A
337
+ m.optional_enum = 100
338
+ assert m.optional_enum == 100
339
+ end
340
+
341
+ def test_dup
342
+ m = TestMessage.new
343
+ m.optional_string = "hello"
344
+ m.optional_int32 = 42
345
+ m.repeated_msg.push TestMessage2.new(:foo => 100)
346
+ m.repeated_msg.push TestMessage2.new(:foo => 200)
347
+
348
+ m2 = m.dup
349
+ assert m == m2
350
+ m.optional_int32 += 1
351
+ assert m != m2
352
+ assert m.repeated_msg[0] == m2.repeated_msg[0]
353
+ assert m.repeated_msg[0].object_id == m2.repeated_msg[0].object_id
354
+ end
355
+
356
+ def test_deep_copy
357
+ m = TestMessage.new(:optional_int32 => 42,
358
+ :repeated_msg => [TestMessage2.new(:foo => 100)])
359
+ m2 = Google::Protobuf.deep_copy(m)
360
+ assert m == m2
361
+ assert m.repeated_msg == m2.repeated_msg
362
+ assert m.repeated_msg.object_id != m2.repeated_msg.object_id
363
+ assert m.repeated_msg[0].object_id != m2.repeated_msg[0].object_id
364
+ end
365
+
366
+ def test_enum_lookup
367
+ assert TestEnum::A == 1
368
+ assert TestEnum::B == 2
369
+ assert TestEnum::C == 3
370
+
371
+ assert TestEnum::lookup(1) == :A
372
+ assert TestEnum::lookup(2) == :B
373
+ assert TestEnum::lookup(3) == :C
374
+
375
+ assert TestEnum::resolve(:A) == 1
376
+ assert TestEnum::resolve(:B) == 2
377
+ assert TestEnum::resolve(:C) == 3
378
+ end
379
+
380
+ def test_parse_serialize
381
+ m = TestMessage.new(:optional_int32 => 42,
382
+ :optional_string => "hello world",
383
+ :optional_enum => :B,
384
+ :repeated_string => ["a", "b", "c"],
385
+ :repeated_int32 => [42, 43, 44],
386
+ :repeated_enum => [:A, :B, :C, 100],
387
+ :repeated_msg => [TestMessage2.new(:foo => 1), TestMessage2.new(:foo => 2)])
388
+ data = TestMessage.encode m
389
+ m2 = TestMessage.decode data
390
+ assert m == m2
391
+
392
+ data = Google::Protobuf.encode m
393
+ m2 = Google::Protobuf.decode(TestMessage, data)
394
+ assert m == m2
395
+ end
396
+
397
+ def test_def_errors
398
+ s = Google::Protobuf::DescriptorPool.new
399
+ assert_raise TypeError do
400
+ s.build do
401
+ # enum with no default (integer value 0)
402
+ add_enum "MyEnum" do
403
+ value :A, 1
404
+ end
405
+ end
406
+ end
407
+ assert_raise TypeError do
408
+ s.build do
409
+ # message with required field (unsupported in proto3)
410
+ add_message "MyMessage" do
411
+ required :foo, :int32, 1
412
+ end
413
+ end
414
+ end
415
+ end
416
+
417
+ def test_corecursive
418
+ # just be sure that we can instantiate types with corecursive field-type
419
+ # references.
420
+ m = Recursive1.new(:foo => Recursive2.new(:foo => Recursive1.new))
421
+ assert Recursive1.descriptor.lookup("foo").subtype ==
422
+ Recursive2.descriptor
423
+ assert Recursive2.descriptor.lookup("foo").subtype ==
424
+ Recursive1.descriptor
425
+
426
+ serialized = Recursive1.encode(m)
427
+ m2 = Recursive1.decode(serialized)
428
+ assert m == m2
429
+ end
430
+
431
+ def test_serialize_cycle
432
+ m = Recursive1.new(:foo => Recursive2.new)
433
+ m.foo.foo = m
434
+ assert_raise RuntimeError do
435
+ serialized = Recursive1.encode(m)
436
+ end
437
+ end
438
+
439
+ def test_bad_field_names
440
+ m = BadFieldNames.new(:dup => 1, :class => 2)
441
+ m2 = m.dup
442
+ assert m == m2
443
+ assert m['dup'] == 1
444
+ assert m['class'] == 2
445
+ m['dup'] = 3
446
+ assert m['dup'] == 3
447
+ m['a.b'] = 4
448
+ assert m['a.b'] == 4
449
+ end
450
+
451
+
452
+ def test_int_ranges
453
+ m = TestMessage.new
454
+
455
+ m.optional_int32 = 0
456
+ m.optional_int32 = -0x8000_0000
457
+ m.optional_int32 = +0x7fff_ffff
458
+ m.optional_int32 = 1.0
459
+ m.optional_int32 = -1.0
460
+ m.optional_int32 = 2e9
461
+ assert_raise RangeError do
462
+ m.optional_int32 = -0x8000_0001
463
+ end
464
+ assert_raise RangeError do
465
+ m.optional_int32 = +0x8000_0000
466
+ end
467
+ assert_raise RangeError do
468
+ m.optional_int32 = +0x1000_0000_0000_0000_0000_0000 # force Bignum
469
+ end
470
+ assert_raise RangeError do
471
+ m.optional_int32 = 1e12
472
+ end
473
+ assert_raise RangeError do
474
+ m.optional_int32 = 1.5
475
+ end
476
+
477
+ m.optional_uint32 = 0
478
+ m.optional_uint32 = +0xffff_ffff
479
+ m.optional_uint32 = 1.0
480
+ m.optional_uint32 = 4e9
481
+ assert_raise RangeError do
482
+ m.optional_uint32 = -1
483
+ end
484
+ assert_raise RangeError do
485
+ m.optional_uint32 = -1.5
486
+ end
487
+ assert_raise RangeError do
488
+ m.optional_uint32 = -1.5e12
489
+ end
490
+ assert_raise RangeError do
491
+ m.optional_uint32 = -0x1000_0000_0000_0000
492
+ end
493
+ assert_raise RangeError do
494
+ m.optional_uint32 = +0x1_0000_0000
495
+ end
496
+ assert_raise RangeError do
497
+ m.optional_uint32 = +0x1000_0000_0000_0000_0000_0000 # force Bignum
498
+ end
499
+ assert_raise RangeError do
500
+ m.optional_uint32 = 1e12
501
+ end
502
+ assert_raise RangeError do
503
+ m.optional_uint32 = 1.5
504
+ end
505
+
506
+ m.optional_int64 = 0
507
+ m.optional_int64 = -0x8000_0000_0000_0000
508
+ m.optional_int64 = +0x7fff_ffff_ffff_ffff
509
+ m.optional_int64 = 1.0
510
+ m.optional_int64 = -1.0
511
+ m.optional_int64 = 8e18
512
+ m.optional_int64 = -8e18
513
+ assert_raise RangeError do
514
+ m.optional_int64 = -0x8000_0000_0000_0001
515
+ end
516
+ assert_raise RangeError do
517
+ m.optional_int64 = +0x8000_0000_0000_0000
518
+ end
519
+ assert_raise RangeError do
520
+ m.optional_int64 = +0x1000_0000_0000_0000_0000_0000 # force Bignum
521
+ end
522
+ assert_raise RangeError do
523
+ m.optional_int64 = 1e50
524
+ end
525
+ assert_raise RangeError do
526
+ m.optional_int64 = 1.5
527
+ end
528
+
529
+ m.optional_uint64 = 0
530
+ m.optional_uint64 = +0xffff_ffff_ffff_ffff
531
+ m.optional_uint64 = 1.0
532
+ m.optional_uint64 = 16e18
533
+ assert_raise RangeError do
534
+ m.optional_uint64 = -1
535
+ end
536
+ assert_raise RangeError do
537
+ m.optional_uint64 = -1.5
538
+ end
539
+ assert_raise RangeError do
540
+ m.optional_uint64 = -1.5e12
541
+ end
542
+ assert_raise RangeError do
543
+ m.optional_uint64 = -0x1_0000_0000_0000_0000
544
+ end
545
+ assert_raise RangeError do
546
+ m.optional_uint64 = +0x1_0000_0000_0000_0000
547
+ end
548
+ assert_raise RangeError do
549
+ m.optional_uint64 = +0x1000_0000_0000_0000_0000_0000 # force Bignum
550
+ end
551
+ assert_raise RangeError do
552
+ m.optional_uint64 = 1e50
553
+ end
554
+ assert_raise RangeError do
555
+ m.optional_uint64 = 1.5
556
+ end
557
+
558
+ end
559
+
560
+ def test_stress_test
561
+ m = TestMessage.new
562
+ m.optional_int32 = 42
563
+ m.optional_int64 = 0x100000000
564
+ m.optional_string = "hello world"
565
+ 10.times do m.repeated_msg.push TestMessage2.new(:foo => 42) end
566
+ 10.times do m.repeated_string.push "hello world" end
567
+
568
+ data = TestMessage.encode(m)
569
+
570
+ l = 0
571
+ 10_000.times do
572
+ m = TestMessage.decode(data)
573
+ data_new = TestMessage.encode(m)
574
+ assert data_new == data
575
+ data = data_new
576
+ end
577
+ end
578
+
579
+ def test_reflection
580
+ m = TestMessage.new(:optional_int32 => 1234)
581
+ msgdef = m.class.descriptor
582
+ assert msgdef.class == Google::Protobuf::Descriptor
583
+ assert msgdef.any? {|field| field.name == "optional_int32"}
584
+ optional_int32 = msgdef.lookup "optional_int32"
585
+ assert optional_int32.class == Google::Protobuf::FieldDescriptor
586
+ assert optional_int32 != nil
587
+ assert optional_int32.name == "optional_int32"
588
+ assert optional_int32.type == :int32
589
+ optional_int32.set(m, 5678)
590
+ assert m.optional_int32 == 5678
591
+ m.optional_int32 = 1000
592
+ assert optional_int32.get(m) == 1000
593
+
594
+ optional_msg = msgdef.lookup "optional_msg"
595
+ assert optional_msg.subtype == TestMessage2.descriptor
596
+
597
+ optional_msg.set(m, optional_msg.subtype.msgclass.new)
598
+
599
+ assert msgdef.msgclass == TestMessage
600
+
601
+ optional_enum = msgdef.lookup "optional_enum"
602
+ assert optional_enum.subtype == TestEnum.descriptor
603
+ assert optional_enum.subtype.class == Google::Protobuf::EnumDescriptor
604
+ optional_enum.subtype.each do |k, v|
605
+ # set with integer, check resolution to symbolic name
606
+ optional_enum.set(m, v)
607
+ assert optional_enum.get(m) == k
608
+ end
609
+ end
610
+
611
+ def test_json
612
+ m = TestMessage.new(:optional_int32 => 1234,
613
+ :optional_int64 => -0x1_0000_0000,
614
+ :optional_uint32 => 0x8000_0000,
615
+ :optional_uint64 => 0xffff_ffff_ffff_ffff,
616
+ :optional_bool => true,
617
+ :optional_float => 1.0,
618
+ :optional_double => -1e100,
619
+ :optional_string => "Test string",
620
+ :optional_bytes => ["FFFFFFFF"].pack('H*'),
621
+ :optional_msg => TestMessage2.new(:foo => 42),
622
+ :repeated_int32 => [1, 2, 3, 4],
623
+ :repeated_string => ["a", "b", "c"],
624
+ :repeated_bool => [true, false, true, false],
625
+ :repeated_msg => [TestMessage2.new(:foo => 1),
626
+ TestMessage2.new(:foo => 2)])
627
+
628
+ json_text = TestMessage.encode_json(m)
629
+ m2 = TestMessage.decode_json(json_text)
630
+ assert m == m2
631
+ end
632
+ end
633
+ end