google-protobuf 3.2.0 → 3.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of google-protobuf might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/ext/google/protobuf_c/defs.c +575 -81
- data/ext/google/protobuf_c/encode_decode.c +456 -149
- data/ext/google/protobuf_c/extconf.rb +15 -2
- data/ext/google/protobuf_c/map.c +47 -3
- data/ext/google/protobuf_c/message.c +308 -82
- data/ext/google/protobuf_c/protobuf.c +7 -3
- data/ext/google/protobuf_c/protobuf.h +86 -12
- data/ext/google/protobuf_c/repeated_field.c +10 -4
- data/ext/google/protobuf_c/storage.c +286 -117
- data/ext/google/protobuf_c/upb.c +14482 -10935
- data/ext/google/protobuf_c/upb.h +2401 -613
- data/ext/google/protobuf_c/wrap_memcpy.c +51 -0
- data/lib/google/protobuf.rb +5 -4
- data/lib/google/protobuf/any_pb.rb +5 -3
- data/lib/google/protobuf/api_pb.rb +23 -21
- data/lib/google/protobuf/duration_pb.rb +5 -3
- data/lib/google/protobuf/empty_pb.rb +3 -1
- data/lib/google/protobuf/field_mask_pb.rb +4 -2
- 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 +4 -2
- data/lib/google/protobuf/struct_pb.rb +19 -17
- data/lib/google/protobuf/timestamp_pb.rb +5 -3
- data/lib/google/protobuf/type_pb.rb +68 -66
- data/lib/google/protobuf/well_known_types.rb +13 -1
- data/lib/google/protobuf/wrappers_pb.rb +28 -26
- data/tests/basic.rb +206 -1023
- data/tests/generated_code_test.rb +6 -2
- metadata +5 -5
@@ -4,32 +4,34 @@
|
|
4
4
|
require 'google/protobuf'
|
5
5
|
|
6
6
|
Google::Protobuf::DescriptorPool.generated_pool.build do
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
7
|
+
add_file("google/protobuf/wrappers.proto", :syntax => :proto3) do
|
8
|
+
add_message "google.protobuf.DoubleValue" do
|
9
|
+
optional :value, :double, 1
|
10
|
+
end
|
11
|
+
add_message "google.protobuf.FloatValue" do
|
12
|
+
optional :value, :float, 1
|
13
|
+
end
|
14
|
+
add_message "google.protobuf.Int64Value" do
|
15
|
+
optional :value, :int64, 1
|
16
|
+
end
|
17
|
+
add_message "google.protobuf.UInt64Value" do
|
18
|
+
optional :value, :uint64, 1
|
19
|
+
end
|
20
|
+
add_message "google.protobuf.Int32Value" do
|
21
|
+
optional :value, :int32, 1
|
22
|
+
end
|
23
|
+
add_message "google.protobuf.UInt32Value" do
|
24
|
+
optional :value, :uint32, 1
|
25
|
+
end
|
26
|
+
add_message "google.protobuf.BoolValue" do
|
27
|
+
optional :value, :bool, 1
|
28
|
+
end
|
29
|
+
add_message "google.protobuf.StringValue" do
|
30
|
+
optional :value, :string, 1
|
31
|
+
end
|
32
|
+
add_message "google.protobuf.BytesValue" do
|
33
|
+
optional :value, :bytes, 1
|
34
|
+
end
|
33
35
|
end
|
34
36
|
end
|
35
37
|
|
data/tests/basic.rb
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
2
|
|
3
|
+
# basic_test_pb.rb is in the same directory as this test.
|
4
|
+
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))
|
5
|
+
|
6
|
+
require 'basic_test_pb'
|
7
|
+
require 'common_tests'
|
3
8
|
require 'google/protobuf'
|
9
|
+
require 'json'
|
4
10
|
require 'test/unit'
|
5
11
|
|
6
12
|
# ------------- generated code --------------
|
@@ -8,623 +14,152 @@ require 'test/unit'
|
|
8
14
|
module BasicTest
|
9
15
|
pool = Google::Protobuf::DescriptorPool.new
|
10
16
|
pool.build do
|
11
|
-
add_message "Foo" do
|
12
|
-
optional :bar, :message, 1, "Bar"
|
13
|
-
repeated :baz, :message, 2, "Baz"
|
14
|
-
end
|
15
|
-
|
16
|
-
add_message "Bar" do
|
17
|
-
optional :msg, :string, 1
|
18
|
-
end
|
19
|
-
|
20
|
-
add_message "Baz" do
|
21
|
-
optional :msg, :string, 1
|
22
|
-
end
|
23
|
-
|
24
|
-
add_message "TestMessage" do
|
25
|
-
optional :optional_int32, :int32, 1
|
26
|
-
optional :optional_int64, :int64, 2
|
27
|
-
optional :optional_uint32, :uint32, 3
|
28
|
-
optional :optional_uint64, :uint64, 4
|
29
|
-
optional :optional_bool, :bool, 5
|
30
|
-
optional :optional_float, :float, 6
|
31
|
-
optional :optional_double, :double, 7
|
32
|
-
optional :optional_string, :string, 8
|
33
|
-
optional :optional_bytes, :bytes, 9
|
34
|
-
optional :optional_msg, :message, 10, "TestMessage2"
|
35
|
-
optional :optional_enum, :enum, 11, "TestEnum"
|
36
|
-
|
37
|
-
repeated :repeated_int32, :int32, 12
|
38
|
-
repeated :repeated_int64, :int64, 13
|
39
|
-
repeated :repeated_uint32, :uint32, 14
|
40
|
-
repeated :repeated_uint64, :uint64, 15
|
41
|
-
repeated :repeated_bool, :bool, 16
|
42
|
-
repeated :repeated_float, :float, 17
|
43
|
-
repeated :repeated_double, :double, 18
|
44
|
-
repeated :repeated_string, :string, 19
|
45
|
-
repeated :repeated_bytes, :bytes, 20
|
46
|
-
repeated :repeated_msg, :message, 21, "TestMessage2"
|
47
|
-
repeated :repeated_enum, :enum, 22, "TestEnum"
|
48
|
-
end
|
49
|
-
add_message "TestMessage2" do
|
50
|
-
optional :foo, :int32, 1
|
51
|
-
end
|
52
|
-
|
53
|
-
add_message "Recursive1" do
|
54
|
-
optional :foo, :message, 1, "Recursive2"
|
55
|
-
end
|
56
|
-
add_message "Recursive2" do
|
57
|
-
optional :foo, :message, 1, "Recursive1"
|
58
|
-
end
|
59
|
-
|
60
|
-
add_enum "TestEnum" do
|
61
|
-
value :Default, 0
|
62
|
-
value :A, 1
|
63
|
-
value :B, 2
|
64
|
-
value :C, 3
|
65
|
-
end
|
66
|
-
|
67
17
|
add_message "BadFieldNames" do
|
68
18
|
optional :dup, :int32, 1
|
69
19
|
optional :class, :int32, 2
|
70
20
|
optional :"a.b", :int32, 3
|
71
21
|
end
|
72
|
-
|
73
|
-
add_message "MapMessage" do
|
74
|
-
map :map_string_int32, :string, :int32, 1
|
75
|
-
map :map_string_msg, :string, :message, 2, "TestMessage2"
|
76
|
-
end
|
77
|
-
add_message "MapMessageWireEquiv" do
|
78
|
-
repeated :map_string_int32, :message, 1, "MapMessageWireEquiv_entry1"
|
79
|
-
repeated :map_string_msg, :message, 2, "MapMessageWireEquiv_entry2"
|
80
|
-
end
|
81
|
-
add_message "MapMessageWireEquiv_entry1" do
|
82
|
-
optional :key, :string, 1
|
83
|
-
optional :value, :int32, 2
|
84
|
-
end
|
85
|
-
add_message "MapMessageWireEquiv_entry2" do
|
86
|
-
optional :key, :string, 1
|
87
|
-
optional :value, :message, 2, "TestMessage2"
|
88
|
-
end
|
89
|
-
|
90
|
-
add_message "OneofMessage" do
|
91
|
-
oneof :my_oneof do
|
92
|
-
optional :a, :string, 1
|
93
|
-
optional :b, :int32, 2
|
94
|
-
optional :c, :message, 3, "TestMessage2"
|
95
|
-
optional :d, :enum, 4, "TestEnum"
|
96
|
-
end
|
97
|
-
end
|
98
22
|
end
|
99
23
|
|
100
|
-
Foo = pool.lookup("Foo").msgclass
|
101
|
-
Bar = pool.lookup("Bar").msgclass
|
102
|
-
Baz = pool.lookup("Baz").msgclass
|
103
|
-
TestMessage = pool.lookup("TestMessage").msgclass
|
104
|
-
TestMessage2 = pool.lookup("TestMessage2").msgclass
|
105
|
-
Recursive1 = pool.lookup("Recursive1").msgclass
|
106
|
-
Recursive2 = pool.lookup("Recursive2").msgclass
|
107
|
-
TestEnum = pool.lookup("TestEnum").enummodule
|
108
24
|
BadFieldNames = pool.lookup("BadFieldNames").msgclass
|
109
|
-
MapMessage = pool.lookup("MapMessage").msgclass
|
110
|
-
MapMessageWireEquiv = pool.lookup("MapMessageWireEquiv").msgclass
|
111
|
-
MapMessageWireEquiv_entry1 =
|
112
|
-
pool.lookup("MapMessageWireEquiv_entry1").msgclass
|
113
|
-
MapMessageWireEquiv_entry2 =
|
114
|
-
pool.lookup("MapMessageWireEquiv_entry2").msgclass
|
115
|
-
OneofMessage = pool.lookup("OneofMessage").msgclass
|
116
25
|
|
117
26
|
# ------------ test cases ---------------
|
118
27
|
|
119
28
|
class MessageContainerTest < Test::Unit::TestCase
|
120
|
-
|
121
|
-
def
|
122
|
-
|
123
|
-
assert m.optional_int32 == 0
|
124
|
-
assert m.optional_int64 == 0
|
125
|
-
assert m.optional_uint32 == 0
|
126
|
-
assert m.optional_uint64 == 0
|
127
|
-
assert m.optional_bool == false
|
128
|
-
assert m.optional_float == 0.0
|
129
|
-
assert m.optional_double == 0.0
|
130
|
-
assert m.optional_string == ""
|
131
|
-
assert m.optional_bytes == ""
|
132
|
-
assert m.optional_msg == nil
|
133
|
-
assert m.optional_enum == :Default
|
29
|
+
# Required by CommonTests module to resolve proto3 proto classes used in tests.
|
30
|
+
def proto_module
|
31
|
+
::BasicTest
|
134
32
|
end
|
33
|
+
include CommonTests
|
135
34
|
|
136
|
-
def
|
35
|
+
def test_has_field
|
137
36
|
m = TestMessage.new
|
138
|
-
m.
|
139
|
-
|
140
|
-
m.
|
141
|
-
assert m
|
142
|
-
|
143
|
-
|
144
|
-
m.
|
145
|
-
|
146
|
-
m.
|
147
|
-
|
148
|
-
|
149
|
-
assert m.optional_float == 0.5
|
150
|
-
m.optional_double = 0.5
|
151
|
-
m.optional_string = "hello"
|
152
|
-
assert m.optional_string == "hello"
|
153
|
-
m.optional_bytes = "world".encode!('ASCII-8BIT')
|
154
|
-
assert m.optional_bytes == "world"
|
155
|
-
m.optional_msg = TestMessage2.new(:foo => 42)
|
156
|
-
assert m.optional_msg == TestMessage2.new(:foo => 42)
|
157
|
-
m.optional_msg = nil
|
158
|
-
assert m.optional_msg == nil
|
159
|
-
end
|
160
|
-
|
161
|
-
def test_ctor_args
|
162
|
-
m = TestMessage.new(:optional_int32 => -42,
|
163
|
-
:optional_msg => TestMessage2.new,
|
164
|
-
:optional_enum => :C,
|
165
|
-
:repeated_string => ["hello", "there", "world"])
|
166
|
-
assert m.optional_int32 == -42
|
167
|
-
assert m.optional_msg.class == TestMessage2
|
168
|
-
assert m.repeated_string.length == 3
|
169
|
-
assert m.optional_enum == :C
|
170
|
-
assert m.repeated_string[0] == "hello"
|
171
|
-
assert m.repeated_string[1] == "there"
|
172
|
-
assert m.repeated_string[2] == "world"
|
173
|
-
end
|
174
|
-
|
175
|
-
def test_inspect
|
176
|
-
m = TestMessage.new(:optional_int32 => -42,
|
177
|
-
:optional_enum => :A,
|
178
|
-
:optional_msg => TestMessage2.new,
|
179
|
-
:repeated_string => ["hello", "there", "world"])
|
180
|
-
expected = '<BasicTest::TestMessage: optional_int32: -42, optional_int64: 0, optional_uint32: 0, optional_uint64: 0, optional_bool: false, optional_float: 0.0, optional_double: 0.0, optional_string: "", optional_bytes: "", optional_msg: <BasicTest::TestMessage2: foo: 0>, optional_enum: :A, repeated_int32: [], repeated_int64: [], repeated_uint32: [], repeated_uint64: [], repeated_bool: [], repeated_float: [], repeated_double: [], repeated_string: ["hello", "there", "world"], repeated_bytes: [], repeated_msg: [], repeated_enum: []>'
|
181
|
-
assert_equal expected, m.inspect
|
182
|
-
end
|
183
|
-
|
184
|
-
def test_hash
|
185
|
-
m1 = TestMessage.new(:optional_int32 => 42)
|
186
|
-
m2 = TestMessage.new(:optional_int32 => 102, repeated_string: ['please', 'work', 'ok?'])
|
187
|
-
m3 = TestMessage.new(:optional_int32 => 102, repeated_string: ['please', 'work', 'ok?'])
|
188
|
-
assert m1.hash != 0
|
189
|
-
assert m2.hash != 0
|
190
|
-
assert m3.hash != 0
|
191
|
-
# relying on the randomness here -- if hash function changes and we are
|
192
|
-
# unlucky enough to get a collision, then change the values above.
|
193
|
-
assert m1.hash != m2.hash
|
194
|
-
assert_equal m2.hash, m3.hash
|
195
|
-
end
|
196
|
-
|
197
|
-
def test_unknown_field_errors
|
198
|
-
e = assert_raise NoMethodError do
|
199
|
-
TestMessage.new.hello
|
37
|
+
assert !m.has_optional_msg?
|
38
|
+
m.optional_msg = TestMessage2.new
|
39
|
+
assert m.has_optional_msg?
|
40
|
+
assert TestMessage.descriptor.lookup('optional_msg').has?(m)
|
41
|
+
|
42
|
+
m = OneofMessage.new
|
43
|
+
assert !m.has_my_oneof?
|
44
|
+
m.a = "foo"
|
45
|
+
assert m.has_my_oneof?
|
46
|
+
assert_raise NoMethodError do
|
47
|
+
m.has_a?
|
200
48
|
end
|
201
|
-
|
202
|
-
|
203
|
-
e = assert_raise NoMethodError do
|
204
|
-
TestMessage.new.hello = "world"
|
205
|
-
end
|
206
|
-
assert_match(/hello/, e.message)
|
207
|
-
end
|
208
|
-
|
209
|
-
def test_initialization_map_errors
|
210
|
-
e = assert_raise ArgumentError do
|
211
|
-
TestMessage.new(:hello => "world")
|
212
|
-
end
|
213
|
-
assert_match(/hello/, e.message)
|
214
|
-
|
215
|
-
e = assert_raise ArgumentError do
|
216
|
-
MapMessage.new(:map_string_int32 => "hello")
|
217
|
-
end
|
218
|
-
assert_equal e.message, "Expected Hash object as initializer value for map field 'map_string_int32'."
|
219
|
-
|
220
|
-
e = assert_raise ArgumentError do
|
221
|
-
TestMessage.new(:repeated_uint32 => "hello")
|
222
|
-
end
|
223
|
-
assert_equal e.message, "Expected array as initializer value for repeated field 'repeated_uint32'."
|
224
|
-
end
|
225
|
-
|
226
|
-
def test_type_errors
|
227
|
-
m = TestMessage.new
|
228
|
-
assert_raise TypeError do
|
229
|
-
m.optional_int32 = "hello"
|
230
|
-
end
|
231
|
-
assert_raise TypeError do
|
232
|
-
m.optional_string = 42
|
233
|
-
end
|
234
|
-
assert_raise TypeError do
|
235
|
-
m.optional_string = nil
|
236
|
-
end
|
237
|
-
assert_raise TypeError do
|
238
|
-
m.optional_bool = 42
|
239
|
-
end
|
240
|
-
assert_raise TypeError do
|
241
|
-
m.optional_msg = TestMessage.new # expects TestMessage2
|
242
|
-
end
|
243
|
-
|
244
|
-
assert_raise TypeError do
|
245
|
-
m.repeated_int32 = [] # needs RepeatedField
|
246
|
-
end
|
247
|
-
|
248
|
-
assert_raise TypeError do
|
249
|
-
m.repeated_int32.push "hello"
|
250
|
-
end
|
251
|
-
|
252
|
-
assert_raise TypeError do
|
253
|
-
m.repeated_msg.push TestMessage.new
|
49
|
+
assert_raise ArgumentError do
|
50
|
+
OneofMessage.descriptor.lookup('a').has?(m)
|
254
51
|
end
|
255
|
-
end
|
256
52
|
|
257
|
-
def test_string_encoding
|
258
53
|
m = TestMessage.new
|
259
|
-
|
260
|
-
|
261
|
-
# ASCII-8BIT to a string field will convert to the proper encoding.
|
262
|
-
m.optional_bytes = "Test string ASCII".encode!('ASCII')
|
263
|
-
assert m.optional_bytes.frozen?
|
264
|
-
assert_equal Encoding::ASCII_8BIT, m.optional_bytes.encoding
|
265
|
-
assert_equal "Test string ASCII", m.optional_bytes
|
266
|
-
|
267
|
-
assert_raise Encoding::UndefinedConversionError do
|
268
|
-
m.optional_bytes = "Test string UTF-8 \u0100".encode!('UTF-8')
|
269
|
-
end
|
270
|
-
|
271
|
-
assert_raise Encoding::UndefinedConversionError do
|
272
|
-
m.optional_string = ["FFFF"].pack('H*')
|
54
|
+
assert_raise NoMethodError do
|
55
|
+
m.has_optional_int32?
|
273
56
|
end
|
274
|
-
|
275
|
-
|
276
|
-
m.optional_bytes = ["FFFF"].pack('H*')
|
277
|
-
m.optional_string = "\u0100"
|
278
|
-
|
279
|
-
# strings are immutable so we can't do this, but serialize should catch it.
|
280
|
-
m.optional_string = "asdf".encode!('UTF-8')
|
281
|
-
assert_raise RuntimeError do
|
282
|
-
m.optional_string.encode!('ASCII-8BIT')
|
57
|
+
assert_raise ArgumentError do
|
58
|
+
TestMessage.descriptor.lookup('optional_int32').has?(m)
|
283
59
|
end
|
284
|
-
end
|
285
|
-
|
286
|
-
def test_rptfield_int32
|
287
|
-
l = Google::Protobuf::RepeatedField.new(:int32)
|
288
|
-
assert l.count == 0
|
289
|
-
l = Google::Protobuf::RepeatedField.new(:int32, [1, 2, 3])
|
290
|
-
assert l.count == 3
|
291
|
-
assert_equal [1, 2, 3], l
|
292
|
-
assert_equal l, [1, 2, 3]
|
293
|
-
l.push 4
|
294
|
-
assert l == [1, 2, 3, 4]
|
295
|
-
dst_list = []
|
296
|
-
l.each { |val| dst_list.push val }
|
297
|
-
assert dst_list == [1, 2, 3, 4]
|
298
|
-
assert l.to_a == [1, 2, 3, 4]
|
299
|
-
assert l[0] == 1
|
300
|
-
assert l[3] == 4
|
301
|
-
l[0] = 5
|
302
|
-
assert l == [5, 2, 3, 4]
|
303
|
-
|
304
|
-
l2 = l.dup
|
305
|
-
assert l == l2
|
306
|
-
assert l.object_id != l2.object_id
|
307
|
-
l2.push 6
|
308
|
-
assert l.count == 4
|
309
|
-
assert l2.count == 5
|
310
60
|
|
311
|
-
|
312
|
-
|
313
|
-
l.concat([7, 8, 9])
|
314
|
-
assert l == [5, 2, 3, 4, 7, 8, 9]
|
315
|
-
assert l.pop == 9
|
316
|
-
assert l == [5, 2, 3, 4, 7, 8]
|
317
|
-
|
318
|
-
assert_raise TypeError do
|
319
|
-
m = TestMessage.new
|
320
|
-
l.push m
|
61
|
+
assert_raise NoMethodError do
|
62
|
+
m.has_optional_string?
|
321
63
|
end
|
322
|
-
|
323
|
-
|
324
|
-
m.repeated_int32 = l
|
325
|
-
assert m.repeated_int32 == [5, 2, 3, 4, 7, 8]
|
326
|
-
assert m.repeated_int32.object_id == l.object_id
|
327
|
-
l.push 42
|
328
|
-
assert m.repeated_int32.pop == 42
|
329
|
-
|
330
|
-
l3 = l + l.dup
|
331
|
-
assert l3.count == l.count * 2
|
332
|
-
l.count.times do |i|
|
333
|
-
assert l3[i] == l[i]
|
334
|
-
assert l3[l.count + i] == l[i]
|
335
|
-
end
|
336
|
-
|
337
|
-
l.clear
|
338
|
-
assert l.count == 0
|
339
|
-
l += [1, 2, 3, 4]
|
340
|
-
l.replace([5, 6, 7, 8])
|
341
|
-
assert l == [5, 6, 7, 8]
|
342
|
-
|
343
|
-
l4 = Google::Protobuf::RepeatedField.new(:int32)
|
344
|
-
l4[5] = 42
|
345
|
-
assert l4 == [0, 0, 0, 0, 0, 42]
|
346
|
-
|
347
|
-
l4 << 100
|
348
|
-
assert l4 == [0, 0, 0, 0, 0, 42, 100]
|
349
|
-
l4 << 101 << 102
|
350
|
-
assert l4 == [0, 0, 0, 0, 0, 42, 100, 101, 102]
|
351
|
-
end
|
352
|
-
|
353
|
-
def test_parent_rptfield
|
354
|
-
#make sure we set the RepeatedField and can add to it
|
355
|
-
m = TestMessage.new
|
356
|
-
assert m.repeated_string == []
|
357
|
-
m.repeated_string << 'ok'
|
358
|
-
m.repeated_string.push('ok2')
|
359
|
-
assert m.repeated_string == ['ok', 'ok2']
|
360
|
-
m.repeated_string += ['ok3']
|
361
|
-
assert m.repeated_string == ['ok', 'ok2', 'ok3']
|
362
|
-
end
|
363
|
-
|
364
|
-
def test_rptfield_msg
|
365
|
-
l = Google::Protobuf::RepeatedField.new(:message, TestMessage)
|
366
|
-
l.push TestMessage.new
|
367
|
-
assert l.count == 1
|
368
|
-
assert_raise TypeError do
|
369
|
-
l.push TestMessage2.new
|
370
|
-
end
|
371
|
-
assert_raise TypeError do
|
372
|
-
l.push 42
|
373
|
-
end
|
374
|
-
|
375
|
-
l2 = l.dup
|
376
|
-
assert l2[0] == l[0]
|
377
|
-
assert l2[0].object_id == l[0].object_id
|
378
|
-
|
379
|
-
l2 = Google::Protobuf.deep_copy(l)
|
380
|
-
assert l2[0] == l[0]
|
381
|
-
assert l2[0].object_id != l[0].object_id
|
382
|
-
|
383
|
-
l3 = l + l2
|
384
|
-
assert l3.count == 2
|
385
|
-
assert l3[0] == l[0]
|
386
|
-
assert l3[1] == l2[0]
|
387
|
-
l3[0].optional_int32 = 1000
|
388
|
-
assert l[0].optional_int32 == 1000
|
389
|
-
|
390
|
-
new_msg = TestMessage.new(:optional_int32 => 200)
|
391
|
-
l4 = l + [new_msg]
|
392
|
-
assert l4.count == 2
|
393
|
-
new_msg.optional_int32 = 1000
|
394
|
-
assert l4[1].optional_int32 == 1000
|
395
|
-
end
|
396
|
-
|
397
|
-
def test_rptfield_enum
|
398
|
-
l = Google::Protobuf::RepeatedField.new(:enum, TestEnum)
|
399
|
-
l.push :A
|
400
|
-
l.push :B
|
401
|
-
l.push :C
|
402
|
-
assert l.count == 3
|
403
|
-
assert_raise RangeError do
|
404
|
-
l.push :D
|
64
|
+
assert_raise ArgumentError do
|
65
|
+
TestMessage.descriptor.lookup('optional_string').has?(m)
|
405
66
|
end
|
406
|
-
assert l[0] == :A
|
407
|
-
|
408
|
-
l.push 4
|
409
|
-
assert l[3] == 4
|
410
|
-
end
|
411
67
|
|
412
|
-
|
413
|
-
|
414
|
-
l = Google::Protobuf::RepeatedField.new
|
68
|
+
assert_raise NoMethodError do
|
69
|
+
m.has_optional_bool?
|
415
70
|
end
|
416
71
|
assert_raise ArgumentError do
|
417
|
-
|
72
|
+
TestMessage.descriptor.lookup('optional_bool').has?(m)
|
418
73
|
end
|
419
|
-
|
420
|
-
|
74
|
+
|
75
|
+
assert_raise NoMethodError do
|
76
|
+
m.has_repeated_msg?
|
421
77
|
end
|
422
78
|
assert_raise ArgumentError do
|
423
|
-
|
79
|
+
TestMessage.descriptor.lookup('repeated_msg').has?(m)
|
424
80
|
end
|
425
81
|
end
|
426
82
|
|
427
|
-
def
|
428
|
-
|
429
|
-
length_methods = %w(count length size)
|
430
|
-
length_methods.each do |lm|
|
431
|
-
assert l.send(lm) == 0
|
432
|
-
end
|
433
|
-
# out of bounds returns a nil
|
434
|
-
assert l[0] == nil
|
435
|
-
assert l[1] == nil
|
436
|
-
assert l[-1] == nil
|
437
|
-
l.push 4
|
438
|
-
length_methods.each do |lm|
|
439
|
-
assert l.send(lm) == 1
|
440
|
-
end
|
441
|
-
assert l[0] == 4
|
442
|
-
assert l[1] == nil
|
443
|
-
assert l[-1] == 4
|
444
|
-
assert l[-2] == nil
|
445
|
-
|
446
|
-
l.push 2
|
447
|
-
length_methods.each do |lm|
|
448
|
-
assert l.send(lm) == 2
|
449
|
-
end
|
450
|
-
assert l[0] == 4
|
451
|
-
assert l[1] == 2
|
452
|
-
assert l[2] == nil
|
453
|
-
assert l[-1] == 2
|
454
|
-
assert l[-2] == 4
|
455
|
-
assert l[-3] == nil
|
83
|
+
def test_set_clear_defaults
|
84
|
+
m = TestMessage.new
|
456
85
|
|
457
|
-
|
458
|
-
|
86
|
+
m.optional_int32 = -42
|
87
|
+
assert_equal -42, m.optional_int32
|
88
|
+
m.clear_optional_int32
|
89
|
+
assert_equal 0, m.optional_int32
|
459
90
|
|
460
|
-
|
461
|
-
|
462
|
-
|
91
|
+
m.optional_int32 = 50
|
92
|
+
assert_equal 50, m.optional_int32
|
93
|
+
TestMessage.descriptor.lookup('optional_int32').clear(m)
|
94
|
+
assert_equal 0, m.optional_int32
|
463
95
|
|
464
|
-
m =
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
assert m == { "jkl;" => 42, "asdf" => 1 }
|
469
|
-
assert m.has_key?("asdf")
|
470
|
-
assert !m.has_key?("qwerty")
|
471
|
-
assert m.length == 2
|
96
|
+
m.optional_string = "foo bar"
|
97
|
+
assert_equal "foo bar", m.optional_string
|
98
|
+
m.clear_optional_string
|
99
|
+
assert_equal "", m.optional_string
|
472
100
|
|
473
|
-
|
474
|
-
assert_equal
|
475
|
-
|
476
|
-
assert_equal
|
101
|
+
m.optional_string = "foo"
|
102
|
+
assert_equal "foo", m.optional_string
|
103
|
+
TestMessage.descriptor.lookup('optional_string').clear(m)
|
104
|
+
assert_equal "", m.optional_string
|
477
105
|
|
478
|
-
|
479
|
-
|
480
|
-
assert
|
106
|
+
m.optional_msg = TestMessage2.new(:foo => 42)
|
107
|
+
assert_equal TestMessage2.new(:foo => 42), m.optional_msg
|
108
|
+
assert m.has_optional_msg?
|
109
|
+
m.clear_optional_msg
|
110
|
+
assert_equal nil, m.optional_msg
|
111
|
+
assert !m.has_optional_msg?
|
481
112
|
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
113
|
+
m.optional_msg = TestMessage2.new(:foo => 42)
|
114
|
+
assert_equal TestMessage2.new(:foo => 42), m.optional_msg
|
115
|
+
TestMessage.descriptor.lookup('optional_msg').clear(m)
|
116
|
+
assert_equal nil, m.optional_msg
|
486
117
|
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
118
|
+
m.repeated_int32.push(1)
|
119
|
+
assert_equal [1], m.repeated_int32
|
120
|
+
m.clear_repeated_int32
|
121
|
+
assert_equal [], m.repeated_int32
|
491
122
|
|
492
|
-
|
493
|
-
|
123
|
+
m.repeated_int32.push(1)
|
124
|
+
assert_equal [1], m.repeated_int32
|
125
|
+
TestMessage.descriptor.lookup('repeated_int32').clear(m)
|
126
|
+
assert_equal [], m.repeated_int32
|
494
127
|
|
495
|
-
m.
|
496
|
-
|
497
|
-
|
128
|
+
m = OneofMessage.new
|
129
|
+
m.a = "foo"
|
130
|
+
assert_equal "foo", m.a
|
131
|
+
assert m.has_my_oneof?
|
132
|
+
m.clear_a
|
133
|
+
assert !m.has_my_oneof?
|
498
134
|
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
m["asdf"] = 0x1_0000_0000
|
504
|
-
end
|
505
|
-
end
|
135
|
+
m.a = "foobar"
|
136
|
+
assert m.has_my_oneof?
|
137
|
+
m.clear_my_oneof
|
138
|
+
assert !m.has_my_oneof?
|
506
139
|
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
140
|
+
m.a = "bar"
|
141
|
+
assert_equal "bar", m.a
|
142
|
+
assert m.has_my_oneof?
|
143
|
+
OneofMessage.descriptor.lookup('a').clear(m)
|
144
|
+
assert !m.has_my_oneof?
|
511
145
|
end
|
512
146
|
|
513
|
-
def test_map_keytypes
|
514
|
-
m = Google::Protobuf::Map.new(:int32, :int32)
|
515
|
-
m[1] = 42
|
516
|
-
m[-1] = 42
|
517
|
-
assert_raise RangeError do
|
518
|
-
m[0x8000_0000] = 1
|
519
|
-
end
|
520
|
-
assert_raise TypeError do
|
521
|
-
m["asdf"] = 1
|
522
|
-
end
|
523
|
-
|
524
|
-
m = Google::Protobuf::Map.new(:int64, :int32)
|
525
|
-
m[0x1000_0000_0000_0000] = 1
|
526
|
-
assert_raise RangeError do
|
527
|
-
m[0x1_0000_0000_0000_0000] = 1
|
528
|
-
end
|
529
|
-
assert_raise TypeError do
|
530
|
-
m["asdf"] = 1
|
531
|
-
end
|
532
147
|
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
m[0x1_0000_0000] = 1
|
537
|
-
end
|
538
|
-
assert_raise RangeError do
|
539
|
-
m[-1] = 1
|
540
|
-
end
|
541
|
-
|
542
|
-
m = Google::Protobuf::Map.new(:uint64, :int32)
|
543
|
-
m[0x8000_0000_0000_0000] = 1
|
544
|
-
assert_raise RangeError do
|
545
|
-
m[0x1_0000_0000_0000_0000] = 1
|
546
|
-
end
|
547
|
-
assert_raise RangeError do
|
548
|
-
m[-1] = 1
|
549
|
-
end
|
550
|
-
|
551
|
-
m = Google::Protobuf::Map.new(:bool, :int32)
|
552
|
-
m[true] = 1
|
553
|
-
m[false] = 2
|
554
|
-
assert_raise TypeError do
|
555
|
-
m[1] = 1
|
556
|
-
end
|
557
|
-
assert_raise TypeError do
|
558
|
-
m["asdf"] = 1
|
559
|
-
end
|
560
|
-
|
561
|
-
m = Google::Protobuf::Map.new(:string, :int32)
|
562
|
-
m["asdf"] = 1
|
563
|
-
assert_raise TypeError do
|
564
|
-
m[1] = 1
|
565
|
-
end
|
566
|
-
assert_raise Encoding::UndefinedConversionError do
|
567
|
-
bytestring = ["FFFF"].pack("H*")
|
568
|
-
m[bytestring] = 1
|
569
|
-
end
|
570
|
-
|
571
|
-
m = Google::Protobuf::Map.new(:bytes, :int32)
|
572
|
-
bytestring = ["FFFF"].pack("H*")
|
573
|
-
m[bytestring] = 1
|
574
|
-
# Allowed -- we will automatically convert to ASCII-8BIT.
|
575
|
-
m["asdf"] = 1
|
576
|
-
assert_raise TypeError do
|
577
|
-
m[1] = 1
|
148
|
+
def test_initialization_map_errors
|
149
|
+
e = assert_raise ArgumentError do
|
150
|
+
TestMessage.new(:hello => "world")
|
578
151
|
end
|
579
|
-
|
152
|
+
assert_match(/hello/, e.message)
|
580
153
|
|
581
|
-
|
582
|
-
|
583
|
-
m["asdf"] = TestMessage.new
|
584
|
-
assert_raise TypeError do
|
585
|
-
m["jkl;"] = TestMessage2.new
|
154
|
+
e = assert_raise ArgumentError do
|
155
|
+
MapMessage.new(:map_string_int32 => "hello")
|
586
156
|
end
|
157
|
+
assert_equal e.message, "Expected Hash object as initializer value for map field 'map_string_int32' (given String)."
|
587
158
|
|
588
|
-
|
589
|
-
:
|
590
|
-
{ "a" => TestMessage.new(:optional_int32 => 42),
|
591
|
-
"b" => TestMessage.new(:optional_int32 => 84) })
|
592
|
-
assert m.length == 2
|
593
|
-
assert m.values.map{|msg| msg.optional_int32}.sort == [42, 84]
|
594
|
-
|
595
|
-
m = Google::Protobuf::Map.new(:string, :enum, TestEnum,
|
596
|
-
{ "x" => :A, "y" => :B, "z" => :C })
|
597
|
-
assert m.length == 3
|
598
|
-
assert m["z"] == :C
|
599
|
-
m["z"] = 2
|
600
|
-
assert m["z"] == :B
|
601
|
-
m["z"] = 4
|
602
|
-
assert m["z"] == 4
|
603
|
-
assert_raise RangeError do
|
604
|
-
m["z"] = :Z
|
605
|
-
end
|
606
|
-
assert_raise TypeError do
|
607
|
-
m["z"] = "z"
|
159
|
+
e = assert_raise ArgumentError do
|
160
|
+
TestMessage.new(:repeated_uint32 => "hello")
|
608
161
|
end
|
609
|
-
|
610
|
-
|
611
|
-
def test_map_dup_deep_copy
|
612
|
-
m = Google::Protobuf::Map.new(
|
613
|
-
:string, :message, TestMessage,
|
614
|
-
{ "a" => TestMessage.new(:optional_int32 => 42),
|
615
|
-
"b" => TestMessage.new(:optional_int32 => 84) })
|
616
|
-
|
617
|
-
m2 = m.dup
|
618
|
-
assert m == m2
|
619
|
-
assert m.object_id != m2.object_id
|
620
|
-
assert m["a"].object_id == m2["a"].object_id
|
621
|
-
assert m["b"].object_id == m2["b"].object_id
|
622
|
-
|
623
|
-
m2 = Google::Protobuf.deep_copy(m)
|
624
|
-
assert m == m2
|
625
|
-
assert m.object_id != m2.object_id
|
626
|
-
assert m["a"].object_id != m2["a"].object_id
|
627
|
-
assert m["b"].object_id != m2["b"].object_id
|
162
|
+
assert_equal e.message, "Expected array as initializer value for repeated field 'repeated_uint32' (given String)."
|
628
163
|
end
|
629
164
|
|
630
165
|
def test_map_field
|
@@ -635,10 +170,12 @@ module BasicTest
|
|
635
170
|
m = MapMessage.new(
|
636
171
|
:map_string_int32 => {"a" => 1, "b" => 2},
|
637
172
|
:map_string_msg => {"a" => TestMessage2.new(:foo => 1),
|
638
|
-
"b" => TestMessage2.new(:foo => 2)}
|
173
|
+
"b" => TestMessage2.new(:foo => 2)},
|
174
|
+
:map_string_enum => {"a" => :A, "b" => :B})
|
639
175
|
assert m.map_string_int32.keys.sort == ["a", "b"]
|
640
176
|
assert m.map_string_int32["a"] == 1
|
641
177
|
assert m.map_string_msg["b"].foo == 2
|
178
|
+
assert m.map_string_enum["a"] == :A
|
642
179
|
|
643
180
|
m.map_string_int32["c"] = 3
|
644
181
|
assert m.map_string_int32["c"] == 3
|
@@ -648,17 +185,17 @@ module BasicTest
|
|
648
185
|
m.map_string_msg.delete("c")
|
649
186
|
assert m.map_string_msg == { "a" => TestMessage2.new(:foo => 1) }
|
650
187
|
|
651
|
-
assert_raise TypeError do
|
188
|
+
assert_raise Google::Protobuf::TypeError do
|
652
189
|
m.map_string_msg["e"] = TestMessage.new # wrong value type
|
653
190
|
end
|
654
191
|
# ensure nothing was added by the above
|
655
192
|
assert m.map_string_msg == { "a" => TestMessage2.new(:foo => 1) }
|
656
193
|
|
657
194
|
m.map_string_int32 = Google::Protobuf::Map.new(:string, :int32)
|
658
|
-
assert_raise TypeError do
|
195
|
+
assert_raise Google::Protobuf::TypeError do
|
659
196
|
m.map_string_int32 = Google::Protobuf::Map.new(:string, :int64)
|
660
197
|
end
|
661
|
-
assert_raise TypeError do
|
198
|
+
assert_raise Google::Protobuf::TypeError do
|
662
199
|
m.map_string_int32 = {}
|
663
200
|
end
|
664
201
|
|
@@ -667,6 +204,16 @@ module BasicTest
|
|
667
204
|
end
|
668
205
|
end
|
669
206
|
|
207
|
+
def test_map_inspect
|
208
|
+
m = MapMessage.new(
|
209
|
+
:map_string_int32 => {"a" => 1, "b" => 2},
|
210
|
+
:map_string_msg => {"a" => TestMessage2.new(:foo => 1),
|
211
|
+
"b" => TestMessage2.new(:foo => 2)},
|
212
|
+
:map_string_enum => {"a" => :A, "b" => :B})
|
213
|
+
expected = "<BasicTest::MapMessage: map_string_int32: {\"b\"=>2, \"a\"=>1}, map_string_msg: {\"b\"=><BasicTest::TestMessage2: foo: 2>, \"a\"=><BasicTest::TestMessage2: foo: 1>}, map_string_enum: {\"b\"=>:B, \"a\"=>:A}>"
|
214
|
+
assert_equal expected, m.inspect
|
215
|
+
end
|
216
|
+
|
670
217
|
def test_map_corruption
|
671
218
|
# This pattern led to a crash in a previous version of upb/protobuf.
|
672
219
|
m = MapMessage.new(map_string_int32: { "aaa" => 1 })
|
@@ -674,11 +221,27 @@ module BasicTest
|
|
674
221
|
m.map_string_int32['aaa'] = 3
|
675
222
|
end
|
676
223
|
|
224
|
+
def test_concurrent_decoding
|
225
|
+
o = Outer.new
|
226
|
+
o.items[0] = Inner.new
|
227
|
+
raw = Outer.encode(o)
|
228
|
+
|
229
|
+
thds = 2.times.map do
|
230
|
+
Thread.new do
|
231
|
+
100000.times do
|
232
|
+
assert_equal o, Outer.decode(raw)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
thds.map(&:join)
|
237
|
+
end
|
238
|
+
|
677
239
|
def test_map_encode_decode
|
678
240
|
m = MapMessage.new(
|
679
241
|
:map_string_int32 => {"a" => 1, "b" => 2},
|
680
242
|
:map_string_msg => {"a" => TestMessage2.new(:foo => 1),
|
681
|
-
"b" => TestMessage2.new(:foo => 2)}
|
243
|
+
"b" => TestMessage2.new(:foo => 2)},
|
244
|
+
:map_string_enum => {"a" => :A, "b" => :B})
|
682
245
|
m2 = MapMessage.decode(MapMessage.encode(m))
|
683
246
|
assert m == m2
|
684
247
|
|
@@ -695,213 +258,21 @@ module BasicTest
|
|
695
258
|
"b" => TestMessage2.new(:foo => 2)}
|
696
259
|
end
|
697
260
|
|
698
|
-
def
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
assert o.name == "my_oneof"
|
704
|
-
oneof_count = 0
|
705
|
-
d.each_oneof{ |oneof|
|
706
|
-
oneof_count += 1
|
707
|
-
assert oneof == o
|
708
|
-
}
|
709
|
-
assert oneof_count == 1
|
710
|
-
assert o.count == 4
|
711
|
-
field_names = o.map{|f| f.name}.sort
|
712
|
-
assert field_names == ["a", "b", "c", "d"]
|
713
|
-
end
|
714
|
-
|
715
|
-
def test_oneof
|
716
|
-
d = OneofMessage.new
|
717
|
-
assert d.a == ""
|
718
|
-
assert d.b == 0
|
719
|
-
assert d.c == nil
|
720
|
-
assert d.d == :Default
|
721
|
-
assert d.my_oneof == nil
|
722
|
-
|
723
|
-
d.a = "hi"
|
724
|
-
assert d.a == "hi"
|
725
|
-
assert d.b == 0
|
726
|
-
assert d.c == nil
|
727
|
-
assert d.d == :Default
|
728
|
-
assert d.my_oneof == :a
|
729
|
-
|
730
|
-
d.b = 42
|
731
|
-
assert d.a == ""
|
732
|
-
assert d.b == 42
|
733
|
-
assert d.c == nil
|
734
|
-
assert d.d == :Default
|
735
|
-
assert d.my_oneof == :b
|
736
|
-
|
737
|
-
d.c = TestMessage2.new(:foo => 100)
|
738
|
-
assert d.a == ""
|
739
|
-
assert d.b == 0
|
740
|
-
assert d.c.foo == 100
|
741
|
-
assert d.d == :Default
|
742
|
-
assert d.my_oneof == :c
|
743
|
-
|
744
|
-
d.d = :C
|
745
|
-
assert d.a == ""
|
746
|
-
assert d.b == 0
|
747
|
-
assert d.c == nil
|
748
|
-
assert d.d == :C
|
749
|
-
assert d.my_oneof == :d
|
750
|
-
|
751
|
-
d2 = OneofMessage.decode(OneofMessage.encode(d))
|
752
|
-
assert d2 == d
|
753
|
-
|
754
|
-
encoded_field_a = OneofMessage.encode(OneofMessage.new(:a => "string"))
|
755
|
-
encoded_field_b = OneofMessage.encode(OneofMessage.new(:b => 1000))
|
756
|
-
encoded_field_c = OneofMessage.encode(
|
757
|
-
OneofMessage.new(:c => TestMessage2.new(:foo => 1)))
|
758
|
-
encoded_field_d = OneofMessage.encode(OneofMessage.new(:d => :B))
|
759
|
-
|
760
|
-
d3 = OneofMessage.decode(
|
761
|
-
encoded_field_c + encoded_field_a + encoded_field_d)
|
762
|
-
assert d3.a == ""
|
763
|
-
assert d3.b == 0
|
764
|
-
assert d3.c == nil
|
765
|
-
assert d3.d == :B
|
766
|
-
|
767
|
-
d4 = OneofMessage.decode(
|
768
|
-
encoded_field_c + encoded_field_a + encoded_field_d +
|
769
|
-
encoded_field_c)
|
770
|
-
assert d4.a == ""
|
771
|
-
assert d4.b == 0
|
772
|
-
assert d4.c.foo == 1
|
773
|
-
assert d4.d == :Default
|
774
|
-
|
775
|
-
d5 = OneofMessage.new(:a => "hello")
|
776
|
-
assert d5.a == "hello"
|
777
|
-
d5.a = nil
|
778
|
-
assert d5.a == ""
|
779
|
-
assert OneofMessage.encode(d5) == ''
|
780
|
-
assert d5.my_oneof == nil
|
781
|
-
end
|
782
|
-
|
783
|
-
def test_enum_field
|
784
|
-
m = TestMessage.new
|
785
|
-
assert m.optional_enum == :Default
|
786
|
-
m.optional_enum = :A
|
787
|
-
assert m.optional_enum == :A
|
788
|
-
assert_raise RangeError do
|
789
|
-
m.optional_enum = :ASDF
|
790
|
-
end
|
791
|
-
m.optional_enum = 1
|
792
|
-
assert m.optional_enum == :A
|
793
|
-
m.optional_enum = 100
|
794
|
-
assert m.optional_enum == 100
|
795
|
-
end
|
796
|
-
|
797
|
-
def test_dup
|
798
|
-
m = TestMessage.new
|
799
|
-
m.optional_string = "hello"
|
800
|
-
m.optional_int32 = 42
|
801
|
-
tm1 = TestMessage2.new(:foo => 100)
|
802
|
-
tm2 = TestMessage2.new(:foo => 200)
|
803
|
-
m.repeated_msg.push tm1
|
804
|
-
assert m.repeated_msg[-1] == tm1
|
805
|
-
m.repeated_msg.push tm2
|
806
|
-
assert m.repeated_msg[-1] == tm2
|
807
|
-
m2 = m.dup
|
808
|
-
assert m == m2
|
809
|
-
m.optional_int32 += 1
|
810
|
-
assert m != m2
|
811
|
-
assert m.repeated_msg[0] == m2.repeated_msg[0]
|
812
|
-
assert m.repeated_msg[0].object_id == m2.repeated_msg[0].object_id
|
813
|
-
end
|
814
|
-
|
815
|
-
def test_deep_copy
|
816
|
-
m = TestMessage.new(:optional_int32 => 42,
|
817
|
-
:repeated_msg => [TestMessage2.new(:foo => 100)])
|
818
|
-
m2 = Google::Protobuf.deep_copy(m)
|
819
|
-
assert m == m2
|
820
|
-
assert m.repeated_msg == m2.repeated_msg
|
821
|
-
assert m.repeated_msg.object_id != m2.repeated_msg.object_id
|
822
|
-
assert m.repeated_msg[0].object_id != m2.repeated_msg[0].object_id
|
823
|
-
end
|
824
|
-
|
825
|
-
def test_eq
|
826
|
-
m = TestMessage.new(:optional_int32 => 42,
|
827
|
-
:repeated_int32 => [1, 2, 3])
|
828
|
-
m2 = TestMessage.new(:optional_int32 => 43,
|
829
|
-
:repeated_int32 => [1, 2, 3])
|
830
|
-
assert m != m2
|
831
|
-
end
|
832
|
-
|
833
|
-
def test_enum_lookup
|
834
|
-
assert TestEnum::A == 1
|
835
|
-
assert TestEnum::B == 2
|
836
|
-
assert TestEnum::C == 3
|
837
|
-
|
838
|
-
assert TestEnum::lookup(1) == :A
|
839
|
-
assert TestEnum::lookup(2) == :B
|
840
|
-
assert TestEnum::lookup(3) == :C
|
841
|
-
|
842
|
-
assert TestEnum::resolve(:A) == 1
|
843
|
-
assert TestEnum::resolve(:B) == 2
|
844
|
-
assert TestEnum::resolve(:C) == 3
|
845
|
-
end
|
846
|
-
|
847
|
-
def test_parse_serialize
|
848
|
-
m = TestMessage.new(:optional_int32 => 42,
|
849
|
-
:optional_string => "hello world",
|
850
|
-
:optional_enum => :B,
|
851
|
-
:repeated_string => ["a", "b", "c"],
|
852
|
-
:repeated_int32 => [42, 43, 44],
|
853
|
-
:repeated_enum => [:A, :B, :C, 100],
|
854
|
-
:repeated_msg => [TestMessage2.new(:foo => 1),
|
855
|
-
TestMessage2.new(:foo => 2)])
|
856
|
-
data = TestMessage.encode m
|
857
|
-
m2 = TestMessage.decode data
|
858
|
-
assert m == m2
|
859
|
-
|
860
|
-
data = Google::Protobuf.encode m
|
861
|
-
m2 = Google::Protobuf.decode(TestMessage, data)
|
862
|
-
assert m == m2
|
863
|
-
end
|
864
|
-
|
865
|
-
def test_encode_decode_helpers
|
866
|
-
m = TestMessage.new(:optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
|
867
|
-
assert_equal 'foo', m.optional_string
|
868
|
-
assert_equal ['bar1', 'bar2'], m.repeated_string
|
261
|
+
def test_protobuf_decode_json_ignore_unknown_fields
|
262
|
+
m = TestMessage.decode_json({
|
263
|
+
optional_string: "foo",
|
264
|
+
not_in_message: "some_value"
|
265
|
+
}.to_json, { ignore_unknown_fields: true })
|
869
266
|
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
assert_equal ['bar1', 'bar2'], m2.repeated_string
|
874
|
-
if RUBY_PLATFORM != "java"
|
875
|
-
assert m2.optional_string.frozen?
|
876
|
-
assert m2.repeated_string[0].frozen?
|
267
|
+
assert_equal m.optional_string, "foo"
|
268
|
+
e = assert_raise Google::Protobuf::ParseError do
|
269
|
+
TestMessage.decode_json({ not_in_message: "some_value" }.to_json)
|
877
270
|
end
|
878
|
-
|
879
|
-
proto = m.to_proto
|
880
|
-
m2 = TestMessage.decode(proto)
|
881
|
-
assert_equal 'foo', m2.optional_string
|
882
|
-
assert_equal ['bar1', 'bar2'], m2.repeated_string
|
883
|
-
end
|
884
|
-
|
885
|
-
def test_protobuf_encode_decode_helpers
|
886
|
-
m = TestMessage.new(:optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
|
887
|
-
encoded_msg = Google::Protobuf.encode(m)
|
888
|
-
assert_equal m.to_proto, encoded_msg
|
889
|
-
|
890
|
-
decoded_msg = Google::Protobuf.decode(TestMessage, encoded_msg)
|
891
|
-
assert_equal TestMessage.decode(m.to_proto), decoded_msg
|
892
|
-
end
|
893
|
-
|
894
|
-
def test_protobuf_encode_decode_json_helpers
|
895
|
-
m = TestMessage.new(:optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
|
896
|
-
encoded_msg = Google::Protobuf.encode_json(m)
|
897
|
-
assert_equal m.to_json, encoded_msg
|
898
|
-
|
899
|
-
decoded_msg = Google::Protobuf.decode_json(TestMessage, encoded_msg)
|
900
|
-
assert_equal TestMessage.decode_json(m.to_json), decoded_msg
|
271
|
+
assert_match(/No such field: not_in_message/, e.message)
|
901
272
|
end
|
902
273
|
|
903
274
|
def test_to_h
|
904
|
-
m = TestMessage.new(:optional_bool => true, :optional_double => -10.100001, :optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
|
275
|
+
m = TestMessage.new(:optional_bool => true, :optional_double => -10.100001, :optional_string => 'foo', :repeated_string => ['bar1', 'bar2'], :repeated_msg => [TestMessage2.new(:foo => 100)])
|
905
276
|
expected_result = {
|
906
277
|
:optional_bool=>true,
|
907
278
|
:optional_bytes=>"",
|
@@ -921,276 +292,51 @@ module BasicTest
|
|
921
292
|
:repeated_float=>[],
|
922
293
|
:repeated_int32=>[],
|
923
294
|
:repeated_int64=>[],
|
924
|
-
:repeated_msg=>[],
|
295
|
+
:repeated_msg=>[{:foo => 100}],
|
925
296
|
:repeated_string=>["bar1", "bar2"],
|
926
297
|
:repeated_uint32=>[],
|
927
298
|
:repeated_uint64=>[]
|
928
299
|
}
|
929
300
|
assert_equal expected_result, m.to_h
|
930
|
-
end
|
931
|
-
|
932
|
-
|
933
|
-
def test_def_errors
|
934
|
-
s = Google::Protobuf::DescriptorPool.new
|
935
|
-
assert_raise TypeError do
|
936
|
-
s.build do
|
937
|
-
# enum with no default (integer value 0)
|
938
|
-
add_enum "MyEnum" do
|
939
|
-
value :A, 1
|
940
|
-
end
|
941
|
-
end
|
942
|
-
end
|
943
|
-
assert_raise TypeError do
|
944
|
-
s.build do
|
945
|
-
# message with required field (unsupported in proto3)
|
946
|
-
add_message "MyMessage" do
|
947
|
-
required :foo, :int32, 1
|
948
|
-
end
|
949
|
-
end
|
950
|
-
end
|
951
|
-
end
|
952
|
-
|
953
|
-
def test_corecursive
|
954
|
-
# just be sure that we can instantiate types with corecursive field-type
|
955
|
-
# references.
|
956
|
-
m = Recursive1.new(:foo => Recursive2.new(:foo => Recursive1.new))
|
957
|
-
assert Recursive1.descriptor.lookup("foo").subtype ==
|
958
|
-
Recursive2.descriptor
|
959
|
-
assert Recursive2.descriptor.lookup("foo").subtype ==
|
960
|
-
Recursive1.descriptor
|
961
301
|
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
end
|
974
|
-
|
975
|
-
def test_bad_field_names
|
976
|
-
m = BadFieldNames.new(:dup => 1, :class => 2)
|
977
|
-
m2 = m.dup
|
978
|
-
assert m == m2
|
979
|
-
assert m['dup'] == 1
|
980
|
-
assert m['class'] == 2
|
981
|
-
m['dup'] = 3
|
982
|
-
assert m['dup'] == 3
|
983
|
-
m['a.b'] = 4
|
984
|
-
assert m['a.b'] == 4
|
985
|
-
end
|
986
|
-
|
987
|
-
def test_int_ranges
|
988
|
-
m = TestMessage.new
|
989
|
-
|
990
|
-
m.optional_int32 = 0
|
991
|
-
m.optional_int32 = -0x8000_0000
|
992
|
-
m.optional_int32 = +0x7fff_ffff
|
993
|
-
m.optional_int32 = 1.0
|
994
|
-
m.optional_int32 = -1.0
|
995
|
-
m.optional_int32 = 2e9
|
996
|
-
assert_raise RangeError do
|
997
|
-
m.optional_int32 = -0x8000_0001
|
998
|
-
end
|
999
|
-
assert_raise RangeError do
|
1000
|
-
m.optional_int32 = +0x8000_0000
|
1001
|
-
end
|
1002
|
-
assert_raise RangeError do
|
1003
|
-
m.optional_int32 = +0x1000_0000_0000_0000_0000_0000 # force Bignum
|
1004
|
-
end
|
1005
|
-
assert_raise RangeError do
|
1006
|
-
m.optional_int32 = 1e12
|
1007
|
-
end
|
1008
|
-
assert_raise RangeError do
|
1009
|
-
m.optional_int32 = 1.5
|
1010
|
-
end
|
1011
|
-
|
1012
|
-
m.optional_uint32 = 0
|
1013
|
-
m.optional_uint32 = +0xffff_ffff
|
1014
|
-
m.optional_uint32 = 1.0
|
1015
|
-
m.optional_uint32 = 4e9
|
1016
|
-
assert_raise RangeError do
|
1017
|
-
m.optional_uint32 = -1
|
1018
|
-
end
|
1019
|
-
assert_raise RangeError do
|
1020
|
-
m.optional_uint32 = -1.5
|
1021
|
-
end
|
1022
|
-
assert_raise RangeError do
|
1023
|
-
m.optional_uint32 = -1.5e12
|
1024
|
-
end
|
1025
|
-
assert_raise RangeError do
|
1026
|
-
m.optional_uint32 = -0x1000_0000_0000_0000
|
1027
|
-
end
|
1028
|
-
assert_raise RangeError do
|
1029
|
-
m.optional_uint32 = +0x1_0000_0000
|
1030
|
-
end
|
1031
|
-
assert_raise RangeError do
|
1032
|
-
m.optional_uint32 = +0x1000_0000_0000_0000_0000_0000 # force Bignum
|
1033
|
-
end
|
1034
|
-
assert_raise RangeError do
|
1035
|
-
m.optional_uint32 = 1e12
|
1036
|
-
end
|
1037
|
-
assert_raise RangeError do
|
1038
|
-
m.optional_uint32 = 1.5
|
1039
|
-
end
|
1040
|
-
|
1041
|
-
m.optional_int64 = 0
|
1042
|
-
m.optional_int64 = -0x8000_0000_0000_0000
|
1043
|
-
m.optional_int64 = +0x7fff_ffff_ffff_ffff
|
1044
|
-
m.optional_int64 = 1.0
|
1045
|
-
m.optional_int64 = -1.0
|
1046
|
-
m.optional_int64 = 8e18
|
1047
|
-
m.optional_int64 = -8e18
|
1048
|
-
assert_raise RangeError do
|
1049
|
-
m.optional_int64 = -0x8000_0000_0000_0001
|
1050
|
-
end
|
1051
|
-
assert_raise RangeError do
|
1052
|
-
m.optional_int64 = +0x8000_0000_0000_0000
|
1053
|
-
end
|
1054
|
-
assert_raise RangeError do
|
1055
|
-
m.optional_int64 = +0x1000_0000_0000_0000_0000_0000 # force Bignum
|
1056
|
-
end
|
1057
|
-
assert_raise RangeError do
|
1058
|
-
m.optional_int64 = 1e50
|
1059
|
-
end
|
1060
|
-
assert_raise RangeError do
|
1061
|
-
m.optional_int64 = 1.5
|
1062
|
-
end
|
1063
|
-
|
1064
|
-
m.optional_uint64 = 0
|
1065
|
-
m.optional_uint64 = +0xffff_ffff_ffff_ffff
|
1066
|
-
m.optional_uint64 = 1.0
|
1067
|
-
m.optional_uint64 = 16e18
|
1068
|
-
assert_raise RangeError do
|
1069
|
-
m.optional_uint64 = -1
|
1070
|
-
end
|
1071
|
-
assert_raise RangeError do
|
1072
|
-
m.optional_uint64 = -1.5
|
1073
|
-
end
|
1074
|
-
assert_raise RangeError do
|
1075
|
-
m.optional_uint64 = -1.5e12
|
1076
|
-
end
|
1077
|
-
assert_raise RangeError do
|
1078
|
-
m.optional_uint64 = -0x1_0000_0000_0000_0000
|
1079
|
-
end
|
1080
|
-
assert_raise RangeError do
|
1081
|
-
m.optional_uint64 = +0x1_0000_0000_0000_0000
|
1082
|
-
end
|
1083
|
-
assert_raise RangeError do
|
1084
|
-
m.optional_uint64 = +0x1000_0000_0000_0000_0000_0000 # force Bignum
|
1085
|
-
end
|
1086
|
-
assert_raise RangeError do
|
1087
|
-
m.optional_uint64 = 1e50
|
1088
|
-
end
|
1089
|
-
assert_raise RangeError do
|
1090
|
-
m.optional_uint64 = 1.5
|
1091
|
-
end
|
1092
|
-
end
|
1093
|
-
|
1094
|
-
def test_stress_test
|
1095
|
-
m = TestMessage.new
|
1096
|
-
m.optional_int32 = 42
|
1097
|
-
m.optional_int64 = 0x100000000
|
1098
|
-
m.optional_string = "hello world"
|
1099
|
-
10.times do m.repeated_msg.push TestMessage2.new(:foo => 42) end
|
1100
|
-
10.times do m.repeated_string.push "hello world" end
|
1101
|
-
|
1102
|
-
data = TestMessage.encode(m)
|
1103
|
-
|
1104
|
-
l = 0
|
1105
|
-
10_000.times do
|
1106
|
-
m = TestMessage.decode(data)
|
1107
|
-
data_new = TestMessage.encode(m)
|
1108
|
-
assert data_new == data
|
1109
|
-
data = data_new
|
1110
|
-
end
|
1111
|
-
end
|
1112
|
-
|
1113
|
-
def test_reflection
|
1114
|
-
m = TestMessage.new(:optional_int32 => 1234)
|
1115
|
-
msgdef = m.class.descriptor
|
1116
|
-
assert msgdef.class == Google::Protobuf::Descriptor
|
1117
|
-
assert msgdef.any? {|field| field.name == "optional_int32"}
|
1118
|
-
optional_int32 = msgdef.lookup "optional_int32"
|
1119
|
-
assert optional_int32.class == Google::Protobuf::FieldDescriptor
|
1120
|
-
assert optional_int32 != nil
|
1121
|
-
assert optional_int32.name == "optional_int32"
|
1122
|
-
assert optional_int32.type == :int32
|
1123
|
-
optional_int32.set(m, 5678)
|
1124
|
-
assert m.optional_int32 == 5678
|
1125
|
-
m.optional_int32 = 1000
|
1126
|
-
assert optional_int32.get(m) == 1000
|
1127
|
-
|
1128
|
-
optional_msg = msgdef.lookup "optional_msg"
|
1129
|
-
assert optional_msg.subtype == TestMessage2.descriptor
|
1130
|
-
|
1131
|
-
optional_msg.set(m, optional_msg.subtype.msgclass.new)
|
1132
|
-
|
1133
|
-
assert msgdef.msgclass == TestMessage
|
1134
|
-
|
1135
|
-
optional_enum = msgdef.lookup "optional_enum"
|
1136
|
-
assert optional_enum.subtype == TestEnum.descriptor
|
1137
|
-
assert optional_enum.subtype.class == Google::Protobuf::EnumDescriptor
|
1138
|
-
optional_enum.subtype.each do |k, v|
|
1139
|
-
# set with integer, check resolution to symbolic name
|
1140
|
-
optional_enum.set(m, v)
|
1141
|
-
assert optional_enum.get(m) == k
|
1142
|
-
end
|
302
|
+
m = MapMessage.new(
|
303
|
+
:map_string_int32 => {"a" => 1, "b" => 2},
|
304
|
+
:map_string_msg => {"a" => TestMessage2.new(:foo => 1),
|
305
|
+
"b" => TestMessage2.new(:foo => 2)},
|
306
|
+
:map_string_enum => {"a" => :A, "b" => :B})
|
307
|
+
expected_result = {
|
308
|
+
:map_string_int32 => {"a" => 1, "b" => 2},
|
309
|
+
:map_string_msg => {"a" => {:foo => 1}, "b" => {:foo => 2}},
|
310
|
+
:map_string_enum => {"a" => :A, "b" => :B}
|
311
|
+
}
|
312
|
+
assert_equal expected_result, m.to_h
|
1143
313
|
end
|
1144
314
|
|
1145
|
-
def test_json
|
1146
|
-
# TODO: Fix JSON in JRuby version.
|
1147
|
-
return if RUBY_PLATFORM == "java"
|
1148
|
-
m = TestMessage.new(:optional_int32 => 1234,
|
1149
|
-
:optional_int64 => -0x1_0000_0000,
|
1150
|
-
:optional_uint32 => 0x8000_0000,
|
1151
|
-
:optional_uint64 => 0xffff_ffff_ffff_ffff,
|
1152
|
-
:optional_bool => true,
|
1153
|
-
:optional_float => 1.0,
|
1154
|
-
:optional_double => -1e100,
|
1155
|
-
:optional_string => "Test string",
|
1156
|
-
:optional_bytes => ["FFFFFFFF"].pack('H*'),
|
1157
|
-
:optional_msg => TestMessage2.new(:foo => 42),
|
1158
|
-
:repeated_int32 => [1, 2, 3, 4],
|
1159
|
-
:repeated_string => ["a", "b", "c"],
|
1160
|
-
:repeated_bool => [true, false, true, false],
|
1161
|
-
:repeated_msg => [TestMessage2.new(:foo => 1),
|
1162
|
-
TestMessage2.new(:foo => 2)])
|
1163
|
-
|
1164
|
-
json_text = TestMessage.encode_json(m)
|
1165
|
-
m2 = TestMessage.decode_json(json_text)
|
1166
|
-
assert m == m2
|
1167
|
-
|
1168
|
-
# Crash case from GitHub issue 283.
|
1169
|
-
bar = Bar.new(msg: "bar")
|
1170
|
-
baz1 = Baz.new(msg: "baz")
|
1171
|
-
baz2 = Baz.new(msg: "quux")
|
1172
|
-
Foo.encode_json(Foo.new)
|
1173
|
-
Foo.encode_json(Foo.new(bar: bar))
|
1174
|
-
Foo.encode_json(Foo.new(bar: bar, baz: [baz1, baz2]))
|
1175
|
-
end
|
1176
315
|
|
1177
316
|
def test_json_maps
|
1178
317
|
# TODO: Fix JSON in JRuby version.
|
1179
318
|
return if RUBY_PLATFORM == "java"
|
1180
319
|
m = MapMessage.new(:map_string_int32 => {"a" => 1})
|
1181
|
-
expected =
|
1182
|
-
expected_preserve =
|
1183
|
-
|
320
|
+
expected = {mapStringInt32: {a: 1}, mapStringMsg: {}, mapStringEnum: {}}
|
321
|
+
expected_preserve = {map_string_int32: {a: 1}, map_string_msg: {}, map_string_enum: {}}
|
322
|
+
assert_equal JSON.parse(MapMessage.encode_json(m), :symbolize_names => true), expected
|
1184
323
|
|
1185
324
|
json = MapMessage.encode_json(m, :preserve_proto_fieldnames => true)
|
1186
|
-
|
325
|
+
assert_equal JSON.parse(json, :symbolize_names => true), expected_preserve
|
1187
326
|
|
1188
327
|
m2 = MapMessage.decode_json(MapMessage.encode_json(m))
|
1189
|
-
|
328
|
+
assert_equal m, m2
|
1190
329
|
end
|
1191
330
|
|
1192
|
-
def
|
1193
|
-
|
331
|
+
def test_json_maps_emit_defaults_submsg
|
332
|
+
# TODO: Fix JSON in JRuby version.
|
333
|
+
return if RUBY_PLATFORM == "java"
|
334
|
+
m = MapMessage.new(:map_string_msg => {"a" => TestMessage2.new})
|
335
|
+
expected = {mapStringInt32: {}, mapStringMsg: {a: {foo: 0}}, mapStringEnum: {}}
|
336
|
+
|
337
|
+
actual = MapMessage.encode_json(m, :emit_defaults => true)
|
338
|
+
|
339
|
+
assert_equal JSON.parse(actual, :symbolize_names => true), expected
|
1194
340
|
end
|
1195
341
|
|
1196
342
|
def test_respond_to
|
@@ -1200,5 +346,42 @@ module BasicTest
|
|
1200
346
|
assert msg.respond_to?(:map_string_int32)
|
1201
347
|
assert !msg.respond_to?(:bacon)
|
1202
348
|
end
|
349
|
+
|
350
|
+
def test_file_descriptor
|
351
|
+
file_descriptor = TestMessage.descriptor.file_descriptor
|
352
|
+
assert nil != file_descriptor
|
353
|
+
assert_equal "tests/basic_test.proto", file_descriptor.name
|
354
|
+
assert_equal :proto3, file_descriptor.syntax
|
355
|
+
|
356
|
+
file_descriptor = TestEnum.descriptor.file_descriptor
|
357
|
+
assert nil != file_descriptor
|
358
|
+
assert_equal "tests/basic_test.proto", file_descriptor.name
|
359
|
+
assert_equal :proto3, file_descriptor.syntax
|
360
|
+
|
361
|
+
file_descriptor = BadFieldNames.descriptor.file_descriptor
|
362
|
+
assert nil != file_descriptor
|
363
|
+
assert_equal nil, file_descriptor.name
|
364
|
+
assert_equal :proto3, file_descriptor.syntax
|
365
|
+
end
|
366
|
+
|
367
|
+
# Ruby 2.5 changed to raise FrozenError instead of RuntimeError
|
368
|
+
FrozenErrorType = Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.5') ? RuntimeError : FrozenError
|
369
|
+
|
370
|
+
def test_map_freeze
|
371
|
+
m = proto_module::MapMessage.new
|
372
|
+
m.map_string_int32['a'] = 5
|
373
|
+
m.map_string_msg['b'] = proto_module::TestMessage2.new
|
374
|
+
|
375
|
+
m.map_string_int32.freeze
|
376
|
+
m.map_string_msg.freeze
|
377
|
+
|
378
|
+
assert m.map_string_int32.frozen?
|
379
|
+
assert m.map_string_msg.frozen?
|
380
|
+
|
381
|
+
assert_raise(FrozenErrorType) { m.map_string_int32['foo'] = 1 }
|
382
|
+
assert_raise(FrozenErrorType) { m.map_string_msg['bar'] = proto_module::TestMessage2.new }
|
383
|
+
assert_raise(FrozenErrorType) { m.map_string_int32.delete('a') }
|
384
|
+
assert_raise(FrozenErrorType) { m.map_string_int32.clear }
|
385
|
+
end
|
1203
386
|
end
|
1204
387
|
end
|