google-protobuf 3.7.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 +4 -4
- 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 +669 -1646
- data/ext/google/protobuf_c/defs.h +107 -0
- data/ext/google/protobuf_c/extconf.rb +13 -8
- data/ext/google/protobuf_c/map.c +330 -477
- data/ext/google/protobuf_c/map.h +66 -0
- data/ext/google/protobuf_c/message.c +1048 -379
- data/ext/google/protobuf_c/message.h +104 -0
- data/ext/google/protobuf_c/protobuf.c +413 -54
- data/ext/google/protobuf_c/protobuf.h +53 -546
- data/ext/google/protobuf_c/repeated_field.c +318 -315
- 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 +4 -3
- data/lib/google/protobuf/any_pb.rb +1 -1
- data/lib/google/protobuf/api_pb.rb +4 -3
- 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 +1 -1
- data/lib/google/protobuf/empty_pb.rb +1 -1
- data/lib/google/protobuf/field_mask_pb.rb +1 -1
- data/lib/google/protobuf/message_exts.rb +2 -2
- data/lib/google/protobuf/source_context_pb.rb +1 -1
- data/lib/google/protobuf/struct_pb.rb +4 -4
- data/lib/google/protobuf/timestamp_pb.rb +1 -1
- data/lib/google/protobuf/type_pb.rb +9 -8
- data/lib/google/protobuf/well_known_types.rb +20 -4
- data/lib/google/protobuf/wrappers_pb.rb +9 -9
- data/lib/google/protobuf.rb +6 -4
- data/tests/basic.rb +380 -71
- data/tests/generated_code_test.rb +0 -0
- data/tests/stress.rb +1 -1
- metadata +27 -30
- data/ext/google/protobuf_c/encode_decode.c +0 -1574
- data/ext/google/protobuf_c/storage.c +0 -1019
- data/ext/google/protobuf_c/upb.c +0 -17318
- data/ext/google/protobuf_c/upb.h +0 -9755
data/tests/basic.rb
CHANGED
@@ -17,7 +17,6 @@ module BasicTest
|
|
17
17
|
add_message "BadFieldNames" do
|
18
18
|
optional :dup, :int32, 1
|
19
19
|
optional :class, :int32, 2
|
20
|
-
optional :"a.b", :int32, 3
|
21
20
|
end
|
22
21
|
end
|
23
22
|
|
@@ -32,12 +31,60 @@ module BasicTest
|
|
32
31
|
end
|
33
32
|
include CommonTests
|
34
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
|
43
|
+
end
|
44
|
+
|
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
|
51
|
+
end
|
52
|
+
|
53
|
+
outer = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("Outer").msgclass
|
54
|
+
|
55
|
+
outer.new(
|
56
|
+
inners: []
|
57
|
+
)['inners'].to_s
|
58
|
+
|
59
|
+
assert_raise Google::Protobuf::TypeError do
|
60
|
+
outer.new(
|
61
|
+
inners: [nil]
|
62
|
+
).to_s
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
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)
|
72
|
+
end
|
73
|
+
|
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
|
80
|
+
end
|
81
|
+
|
35
82
|
def test_has_field
|
36
|
-
m =
|
37
|
-
assert !m.
|
38
|
-
m.
|
39
|
-
assert m.
|
40
|
-
assert
|
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)
|
41
88
|
|
42
89
|
m = OneofMessage.new
|
43
90
|
assert !m.has_my_oneof?
|
@@ -46,32 +93,31 @@ module BasicTest
|
|
46
93
|
assert_raise NoMethodError do
|
47
94
|
m.has_a?
|
48
95
|
end
|
49
|
-
|
50
|
-
OneofMessage.descriptor.lookup('a').has?(m)
|
51
|
-
end
|
96
|
+
assert_true OneofMessage.descriptor.lookup('a').has?(m)
|
52
97
|
|
53
|
-
m =
|
98
|
+
m = TestSingularFields.new
|
54
99
|
assert_raise NoMethodError do
|
55
|
-
m.
|
100
|
+
m.has_singular_int32?
|
56
101
|
end
|
57
102
|
assert_raise ArgumentError do
|
58
|
-
|
103
|
+
TestSingularFields.descriptor.lookup('singular_int32').has?(m)
|
59
104
|
end
|
60
105
|
|
61
106
|
assert_raise NoMethodError do
|
62
|
-
m.
|
107
|
+
m.has_singular_string?
|
63
108
|
end
|
64
109
|
assert_raise ArgumentError do
|
65
|
-
|
110
|
+
TestSingularFields.descriptor.lookup('singular_string').has?(m)
|
66
111
|
end
|
67
112
|
|
68
113
|
assert_raise NoMethodError do
|
69
|
-
m.
|
114
|
+
m.has_singular_bool?
|
70
115
|
end
|
71
116
|
assert_raise ArgumentError do
|
72
|
-
|
117
|
+
TestSingularFields.descriptor.lookup('singular_bool').has?(m)
|
73
118
|
end
|
74
119
|
|
120
|
+
m = TestMessage.new
|
75
121
|
assert_raise NoMethodError do
|
76
122
|
m.has_repeated_msg?
|
77
123
|
end
|
@@ -80,40 +126,70 @@ module BasicTest
|
|
80
126
|
end
|
81
127
|
end
|
82
128
|
|
129
|
+
def test_no_presence
|
130
|
+
m = TestSingularFields.new
|
131
|
+
|
132
|
+
# Explicitly setting to zero does not cause anything to be serialized.
|
133
|
+
m.singular_int32 = 0
|
134
|
+
assert_equal "", TestSingularFields.encode(m)
|
135
|
+
|
136
|
+
# Explicitly setting to a non-zero value *does* cause serialization.
|
137
|
+
m.singular_int32 = 1
|
138
|
+
assert_not_equal "", TestSingularFields.encode(m)
|
139
|
+
|
140
|
+
m.singular_int32 = 0
|
141
|
+
assert_equal "", TestSingularFields.encode(m)
|
142
|
+
end
|
143
|
+
|
83
144
|
def test_set_clear_defaults
|
145
|
+
m = TestSingularFields.new
|
146
|
+
|
147
|
+
m.singular_int32 = -42
|
148
|
+
assert_equal -42, m.singular_int32
|
149
|
+
m.clear_singular_int32
|
150
|
+
assert_equal 0, m.singular_int32
|
151
|
+
|
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
|
156
|
+
|
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
|
161
|
+
|
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?
|
173
|
+
|
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
|
178
|
+
end
|
179
|
+
|
180
|
+
def test_import_proto2
|
84
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)
|
85
186
|
|
86
|
-
m.
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
m
|
92
|
-
assert_equal 50, m.optional_int32
|
93
|
-
TestMessage.descriptor.lookup('optional_int32').clear(m)
|
94
|
-
assert_equal 0, m.optional_int32
|
95
|
-
|
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
|
100
|
-
|
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
|
105
|
-
|
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?
|
112
|
-
|
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
|
187
|
+
m.clear_optional_proto2_submessage
|
188
|
+
assert !m.has_optional_proto2_submessage?
|
189
|
+
end
|
190
|
+
|
191
|
+
def test_clear_repeated_fields
|
192
|
+
m = TestMessage.new
|
117
193
|
|
118
194
|
m.repeated_int32.push(1)
|
119
195
|
assert_equal [1], m.repeated_int32
|
@@ -129,6 +205,7 @@ module BasicTest
|
|
129
205
|
m.a = "foo"
|
130
206
|
assert_equal "foo", m.a
|
131
207
|
assert m.has_my_oneof?
|
208
|
+
assert_equal :a, m.my_oneof
|
132
209
|
m.clear_a
|
133
210
|
assert !m.has_my_oneof?
|
134
211
|
|
@@ -144,7 +221,6 @@ module BasicTest
|
|
144
221
|
assert !m.has_my_oneof?
|
145
222
|
end
|
146
223
|
|
147
|
-
|
148
224
|
def test_initialization_map_errors
|
149
225
|
e = assert_raise ArgumentError do
|
150
226
|
TestMessage.new(:hello => "world")
|
@@ -154,12 +230,12 @@ module BasicTest
|
|
154
230
|
e = assert_raise ArgumentError do
|
155
231
|
MapMessage.new(:map_string_int32 => "hello")
|
156
232
|
end
|
157
|
-
assert_equal e.message, "Expected Hash object as initializer value for map field 'map_string_int32'."
|
233
|
+
assert_equal e.message, "Expected Hash object as initializer value for map field 'map_string_int32' (given String)."
|
158
234
|
|
159
235
|
e = assert_raise ArgumentError do
|
160
236
|
TestMessage.new(:repeated_uint32 => "hello")
|
161
237
|
end
|
162
|
-
assert_equal e.message, "Expected array as initializer value for repeated field 'repeated_uint32'."
|
238
|
+
assert_equal e.message, "Expected array as initializer value for repeated field 'repeated_uint32' (given String)."
|
163
239
|
end
|
164
240
|
|
165
241
|
def test_map_field
|
@@ -170,10 +246,12 @@ module BasicTest
|
|
170
246
|
m = MapMessage.new(
|
171
247
|
:map_string_int32 => {"a" => 1, "b" => 2},
|
172
248
|
:map_string_msg => {"a" => TestMessage2.new(:foo => 1),
|
173
|
-
"b" => TestMessage2.new(:foo => 2)}
|
249
|
+
"b" => TestMessage2.new(:foo => 2)},
|
250
|
+
:map_string_enum => {"a" => :A, "b" => :B})
|
174
251
|
assert m.map_string_int32.keys.sort == ["a", "b"]
|
175
252
|
assert m.map_string_int32["a"] == 1
|
176
253
|
assert m.map_string_msg["b"].foo == 2
|
254
|
+
assert m.map_string_enum["a"] == :A
|
177
255
|
|
178
256
|
m.map_string_int32["c"] = 3
|
179
257
|
assert m.map_string_int32["c"] == 3
|
@@ -197,18 +275,37 @@ module BasicTest
|
|
197
275
|
m.map_string_int32 = {}
|
198
276
|
end
|
199
277
|
|
200
|
-
assert_raise TypeError do
|
278
|
+
assert_raise Google::Protobuf::TypeError do
|
201
279
|
m = MapMessage.new(:map_string_int32 => { 1 => "I am not a number" })
|
202
280
|
end
|
203
281
|
end
|
204
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
|
+
|
205
297
|
def test_map_inspect
|
206
298
|
m = MapMessage.new(
|
207
299
|
:map_string_int32 => {"a" => 1, "b" => 2},
|
208
300
|
:map_string_msg => {"a" => TestMessage2.new(:foo => 1),
|
209
|
-
"b" => TestMessage2.new(:foo => 2)}
|
210
|
-
|
211
|
-
|
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}"
|
212
309
|
end
|
213
310
|
|
214
311
|
def test_map_corruption
|
@@ -218,6 +315,128 @@ module BasicTest
|
|
218
315
|
m.map_string_int32['aaa'] = 3
|
219
316
|
end
|
220
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
|
+
|
221
440
|
def test_concurrent_decoding
|
222
441
|
o = Outer.new
|
223
442
|
o.items[0] = Inner.new
|
@@ -237,7 +456,8 @@ module BasicTest
|
|
237
456
|
m = MapMessage.new(
|
238
457
|
:map_string_int32 => {"a" => 1, "b" => 2},
|
239
458
|
:map_string_msg => {"a" => TestMessage2.new(:foo => 1),
|
240
|
-
"b" => TestMessage2.new(:foo => 2)}
|
459
|
+
"b" => TestMessage2.new(:foo => 2)},
|
460
|
+
:map_string_enum => {"a" => :A, "b" => :B})
|
241
461
|
m2 = MapMessage.decode(MapMessage.encode(m))
|
242
462
|
assert m == m2
|
243
463
|
|
@@ -267,6 +487,14 @@ module BasicTest
|
|
267
487
|
assert_match(/No such field: not_in_message/, e.message)
|
268
488
|
end
|
269
489
|
|
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
|
497
|
+
|
270
498
|
def test_to_h
|
271
499
|
m = TestMessage.new(:optional_bool => true, :optional_double => -10.100001, :optional_string => 'foo', :repeated_string => ['bar1', 'bar2'], :repeated_msg => [TestMessage2.new(:foo => 100)])
|
272
500
|
expected_result = {
|
@@ -278,6 +506,8 @@ module BasicTest
|
|
278
506
|
:optional_int32=>0,
|
279
507
|
:optional_int64=>0,
|
280
508
|
:optional_msg=>nil,
|
509
|
+
:optional_msg2=>nil,
|
510
|
+
:optional_proto2_submessage=>nil,
|
281
511
|
:optional_string=>"foo",
|
282
512
|
:optional_uint32=>0,
|
283
513
|
:optional_uint64=>0,
|
@@ -298,10 +528,12 @@ module BasicTest
|
|
298
528
|
m = MapMessage.new(
|
299
529
|
:map_string_int32 => {"a" => 1, "b" => 2},
|
300
530
|
:map_string_msg => {"a" => TestMessage2.new(:foo => 1),
|
301
|
-
"b" => TestMessage2.new(:foo => 2)}
|
531
|
+
"b" => TestMessage2.new(:foo => 2)},
|
532
|
+
:map_string_enum => {"a" => :A, "b" => :B})
|
302
533
|
expected_result = {
|
303
534
|
:map_string_int32 => {"a" => 1, "b" => 2},
|
304
|
-
:map_string_msg => {"a" => {:foo => 1}, "b" => {:foo => 2}}
|
535
|
+
:map_string_msg => {"a" => {:foo => 1}, "b" => {:foo => 2}},
|
536
|
+
:map_string_enum => {"a" => :A, "b" => :B}
|
305
537
|
}
|
306
538
|
assert_equal expected_result, m.to_h
|
307
539
|
end
|
@@ -311,26 +543,50 @@ module BasicTest
|
|
311
543
|
# TODO: Fix JSON in JRuby version.
|
312
544
|
return if RUBY_PLATFORM == "java"
|
313
545
|
m = MapMessage.new(:map_string_int32 => {"a" => 1})
|
314
|
-
expected = {mapStringInt32: {a: 1}, mapStringMsg: {}}
|
315
|
-
expected_preserve = {map_string_int32: {a: 1}, map_string_msg: {}}
|
316
|
-
|
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
|
317
549
|
|
318
|
-
json = MapMessage.encode_json(m, :preserve_proto_fieldnames => true)
|
319
|
-
|
550
|
+
json = MapMessage.encode_json(m, :preserve_proto_fieldnames => true, :emit_defaults=>true)
|
551
|
+
assert_equal JSON.parse(json, :symbolize_names => true), expected_preserve
|
320
552
|
|
321
553
|
m2 = MapMessage.decode_json(MapMessage.encode_json(m))
|
322
|
-
|
554
|
+
assert_equal m, m2
|
323
555
|
end
|
324
556
|
|
325
557
|
def test_json_maps_emit_defaults_submsg
|
326
558
|
# TODO: Fix JSON in JRuby version.
|
327
559
|
return if RUBY_PLATFORM == "java"
|
328
|
-
m = MapMessage.new(:map_string_msg => {"a" => TestMessage2.new})
|
329
|
-
expected = {mapStringInt32: {}, mapStringMsg: {a: {foo: 0}}}
|
560
|
+
m = MapMessage.new(:map_string_msg => {"a" => TestMessage2.new(foo: 0)})
|
561
|
+
expected = {mapStringInt32: {}, mapStringMsg: {a: {foo: 0}}, mapStringEnum: {}}
|
330
562
|
|
331
563
|
actual = MapMessage.encode_json(m, :emit_defaults => true)
|
332
564
|
|
333
|
-
|
565
|
+
assert_equal JSON.parse(actual, :symbolize_names => true), expected
|
566
|
+
end
|
567
|
+
|
568
|
+
def test_json_emit_defaults_submsg
|
569
|
+
# TODO: Fix JSON in JRuby version.
|
570
|
+
return if RUBY_PLATFORM == "java"
|
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
|
+
}
|
586
|
+
|
587
|
+
actual = proto_module::TestMessage.encode_json(m, :emit_defaults => true)
|
588
|
+
|
589
|
+
assert_equal expected, JSON.parse(actual, :symbolize_names => true)
|
334
590
|
end
|
335
591
|
|
336
592
|
def test_respond_to
|
@@ -351,11 +607,64 @@ module BasicTest
|
|
351
607
|
assert nil != file_descriptor
|
352
608
|
assert_equal "tests/basic_test.proto", file_descriptor.name
|
353
609
|
assert_equal :proto3, file_descriptor.syntax
|
610
|
+
end
|
354
611
|
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
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
|
359
668
|
end
|
360
669
|
end
|
361
670
|
end
|
File without changes
|