google-protobuf 3.4.0.2 → 3.19.4
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.
- checksums.yaml +5 -5
- data/ext/google/protobuf_c/convert.c +348 -0
- data/ext/google/protobuf_c/convert.h +72 -0
- data/ext/google/protobuf_c/defs.c +709 -1188
- data/ext/google/protobuf_c/defs.h +107 -0
- data/ext/google/protobuf_c/extconf.rb +7 -4
- data/ext/google/protobuf_c/map.c +316 -463
- data/ext/google/protobuf_c/map.h +67 -0
- data/ext/google/protobuf_c/message.c +993 -296
- data/ext/google/protobuf_c/message.h +101 -0
- data/ext/google/protobuf_c/protobuf.c +403 -50
- data/ext/google/protobuf_c/protobuf.h +47 -473
- data/ext/google/protobuf_c/repeated_field.c +314 -309
- data/ext/google/protobuf_c/repeated_field.h +63 -0
- data/ext/google/protobuf_c/ruby-upb.c +9171 -0
- data/ext/google/protobuf_c/ruby-upb.h +4704 -0
- data/ext/google/protobuf_c/wrap_memcpy.c +1 -1
- data/lib/google/protobuf/any_pb.rb +6 -4
- data/lib/google/protobuf/api_pb.rb +27 -24
- data/lib/google/protobuf/descriptor_dsl.rb +458 -0
- data/lib/google/protobuf/descriptor_pb.rb +268 -0
- data/lib/google/protobuf/duration_pb.rb +6 -4
- data/lib/google/protobuf/empty_pb.rb +4 -2
- data/lib/google/protobuf/field_mask_pb.rb +5 -3
- data/lib/google/protobuf/message_exts.rb +2 -2
- data/lib/google/protobuf/repeated_field.rb +3 -3
- data/lib/google/protobuf/source_context_pb.rb +5 -3
- data/lib/google/protobuf/struct_pb.rb +23 -21
- data/lib/google/protobuf/timestamp_pb.rb +6 -4
- data/lib/google/protobuf/type_pb.rb +77 -74
- data/lib/google/protobuf/well_known_types.rb +25 -2
- data/lib/google/protobuf/wrappers_pb.rb +37 -35
- data/lib/google/protobuf.rb +7 -4
- data/tests/basic.rb +432 -1115
- data/tests/generated_code_test.rb +6 -2
- data/tests/stress.rb +1 -1
- metadata +22 -30
- data/ext/google/protobuf_c/encode_decode.c +0 -1311
- data/ext/google/protobuf_c/storage.c +0 -893
- data/ext/google/protobuf_c/upb.c +0 -13911
- 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
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
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
|
-
|
205
|
-
|
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
|
-
|
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
|
-
|
217
|
-
|
218
|
-
|
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
|
-
|
222
|
-
|
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
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
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
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
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
|
288
|
-
|
289
|
-
assert
|
290
|
-
|
291
|
-
assert
|
292
|
-
|
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 =
|
325
|
-
m.
|
326
|
-
|
327
|
-
assert m.
|
328
|
-
|
329
|
-
|
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
|
-
|
339
|
-
|
340
|
-
|
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
|
-
|
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
|
-
|
414
|
-
|
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
|
-
|
110
|
+
TestSingularFields.descriptor.lookup('singular_string').has?(m)
|
419
111
|
end
|
420
|
-
|
421
|
-
|
112
|
+
|
113
|
+
assert_raise NoMethodError do
|
114
|
+
m.has_singular_bool?
|
422
115
|
end
|
423
116
|
assert_raise ArgumentError do
|
424
|
-
|
117
|
+
TestSingularFields.descriptor.lookup('singular_bool').has?(m)
|
425
118
|
end
|
426
|
-
end
|
427
119
|
|
428
|
-
|
429
|
-
|
430
|
-
|
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
|
-
|
443
|
-
|
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
|
462
|
-
|
463
|
-
# :int32, :int64, :uint32, :uint64, :bool, :string, :bytes.
|
129
|
+
def test_no_presence
|
130
|
+
m = TestSingularFields.new
|
464
131
|
|
465
|
-
|
466
|
-
m
|
467
|
-
|
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
|
-
|
475
|
-
|
476
|
-
|
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
|
-
|
480
|
-
|
481
|
-
|
140
|
+
m.singular_int32 = 0
|
141
|
+
assert_equal "", TestSingularFields.encode(m)
|
142
|
+
end
|
482
143
|
|
483
|
-
|
484
|
-
|
485
|
-
assert m["asdf"] == nil
|
486
|
-
assert !m.has_key?("asdf")
|
144
|
+
def test_set_clear_defaults
|
145
|
+
m = TestSingularFields.new
|
487
146
|
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
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
|
-
|
494
|
-
|
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.
|
497
|
-
|
498
|
-
|
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
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
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
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
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
|
515
|
-
m =
|
516
|
-
m
|
517
|
-
m
|
518
|
-
|
519
|
-
|
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
|
526
|
-
m
|
527
|
-
|
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
|
-
|
535
|
-
m
|
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
|
544
|
-
|
545
|
-
|
546
|
-
|
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
|
553
|
-
|
554
|
-
m
|
555
|
-
|
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 =
|
563
|
-
m
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
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 =
|
573
|
-
|
574
|
-
m
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
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
|
583
|
-
|
584
|
-
|
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
|
-
|
590
|
-
:
|
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
|
-
|
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
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
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
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
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
|
-
|
862
|
-
|
863
|
-
|
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
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
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
|
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 =
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
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
|
-
|
1182
|
-
|
1183
|
-
|
1184
|
-
|
1185
|
-
|
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
|
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 =
|
560
|
+
m = MapMessage.new(:map_string_msg => {"a" => TestMessage2.new(foo: 0)})
|
561
|
+
expected = {mapStringInt32: {}, mapStringMsg: {a: {foo: 0}}, mapStringEnum: {}}
|
1194
562
|
|
1195
|
-
|
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
|
-
|
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 =
|
571
|
+
m = TestSingularFields.new(singular_msg: proto_module::TestMessage2.new)
|
1228
572
|
|
1229
573
|
expected = {
|
1230
|
-
|
1231
|
-
|
1232
|
-
|
1233
|
-
|
1234
|
-
|
1235
|
-
|
1236
|
-
|
1237
|
-
|
1238
|
-
|
1239
|
-
|
1240
|
-
|
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
|
-
|
589
|
+
assert_equal expected, JSON.parse(actual, :symbolize_names => true)
|
1257
590
|
end
|
1258
591
|
|
1259
|
-
def
|
1260
|
-
#
|
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
|
-
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
1294
|
-
|
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
|
-
|
1305
|
-
|
1306
|
-
|
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
|
-
|
1309
|
-
|
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
|
-
|
623
|
+
assert m.map_string_int32.frozen?
|
624
|
+
assert m.map_string_msg.frozen?
|
1315
625
|
|
1316
|
-
|
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
|
1320
|
-
|
1321
|
-
|
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
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
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
|