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