xref: /aosp_15_r20/external/protobuf/ruby/tests/basic.rb (revision 1b3f573f81763fcece89efc2b6a5209149e44ab8)
1*1b3f573fSAndroid Build Coastguard Worker#!/usr/bin/ruby
2*1b3f573fSAndroid Build Coastguard Worker
3*1b3f573fSAndroid Build Coastguard Worker# basic_test_pb.rb is in the same directory as this test.
4*1b3f573fSAndroid Build Coastguard Worker$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))
5*1b3f573fSAndroid Build Coastguard Worker
6*1b3f573fSAndroid Build Coastguard Workerrequire 'basic_test_pb'
7*1b3f573fSAndroid Build Coastguard Workerrequire 'common_tests'
8*1b3f573fSAndroid Build Coastguard Workerrequire 'google/protobuf'
9*1b3f573fSAndroid Build Coastguard Workerrequire 'json'
10*1b3f573fSAndroid Build Coastguard Workerrequire 'test/unit'
11*1b3f573fSAndroid Build Coastguard Worker
12*1b3f573fSAndroid Build Coastguard Worker# ------------- generated code --------------
13*1b3f573fSAndroid Build Coastguard Worker
14*1b3f573fSAndroid Build Coastguard Workermodule BasicTest
15*1b3f573fSAndroid Build Coastguard Worker  pool = Google::Protobuf::DescriptorPool.new
16*1b3f573fSAndroid Build Coastguard Worker  pool.build do
17*1b3f573fSAndroid Build Coastguard Worker    add_message "BadFieldNames" do
18*1b3f573fSAndroid Build Coastguard Worker      optional :dup, :int32, 1
19*1b3f573fSAndroid Build Coastguard Worker      optional :class, :int32, 2
20*1b3f573fSAndroid Build Coastguard Worker    end
21*1b3f573fSAndroid Build Coastguard Worker  end
22*1b3f573fSAndroid Build Coastguard Worker
23*1b3f573fSAndroid Build Coastguard Worker  BadFieldNames = pool.lookup("BadFieldNames").msgclass
24*1b3f573fSAndroid Build Coastguard Worker
25*1b3f573fSAndroid Build Coastguard Worker# ------------ test cases ---------------
26*1b3f573fSAndroid Build Coastguard Worker
27*1b3f573fSAndroid Build Coastguard Worker  class MessageContainerTest < Test::Unit::TestCase
28*1b3f573fSAndroid Build Coastguard Worker    # Required by CommonTests module to resolve proto3 proto classes used in tests.
29*1b3f573fSAndroid Build Coastguard Worker    def proto_module
30*1b3f573fSAndroid Build Coastguard Worker      ::BasicTest
31*1b3f573fSAndroid Build Coastguard Worker    end
32*1b3f573fSAndroid Build Coastguard Worker    include CommonTests
33*1b3f573fSAndroid Build Coastguard Worker
34*1b3f573fSAndroid Build Coastguard Worker    def test_issue_8311_crash
35*1b3f573fSAndroid Build Coastguard Worker      Google::Protobuf::DescriptorPool.generated_pool.build do
36*1b3f573fSAndroid Build Coastguard Worker        add_file("inner.proto", :syntax => :proto3) do
37*1b3f573fSAndroid Build Coastguard Worker          add_message "Inner" do
38*1b3f573fSAndroid Build Coastguard Worker            # Removing either of these fixes the segfault.
39*1b3f573fSAndroid Build Coastguard Worker            optional :foo, :string, 1
40*1b3f573fSAndroid Build Coastguard Worker            optional :bar, :string, 2
41*1b3f573fSAndroid Build Coastguard Worker          end
42*1b3f573fSAndroid Build Coastguard Worker        end
43*1b3f573fSAndroid Build Coastguard Worker      end
44*1b3f573fSAndroid Build Coastguard Worker
45*1b3f573fSAndroid Build Coastguard Worker      Google::Protobuf::DescriptorPool.generated_pool.build do
46*1b3f573fSAndroid Build Coastguard Worker        add_file("outer.proto", :syntax => :proto3) do
47*1b3f573fSAndroid Build Coastguard Worker          add_message "Outer" do
48*1b3f573fSAndroid Build Coastguard Worker            repeated :inners, :message, 1, "Inner"
49*1b3f573fSAndroid Build Coastguard Worker          end
50*1b3f573fSAndroid Build Coastguard Worker        end
51*1b3f573fSAndroid Build Coastguard Worker      end
52*1b3f573fSAndroid Build Coastguard Worker
53*1b3f573fSAndroid Build Coastguard Worker      outer = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("Outer").msgclass
54*1b3f573fSAndroid Build Coastguard Worker
55*1b3f573fSAndroid Build Coastguard Worker      outer.new(
56*1b3f573fSAndroid Build Coastguard Worker          inners: []
57*1b3f573fSAndroid Build Coastguard Worker      )['inners'].to_s
58*1b3f573fSAndroid Build Coastguard Worker
59*1b3f573fSAndroid Build Coastguard Worker      assert_raise Google::Protobuf::TypeError do
60*1b3f573fSAndroid Build Coastguard Worker        outer.new(
61*1b3f573fSAndroid Build Coastguard Worker            inners: [nil]
62*1b3f573fSAndroid Build Coastguard Worker        ).to_s
63*1b3f573fSAndroid Build Coastguard Worker      end
64*1b3f573fSAndroid Build Coastguard Worker    end
65*1b3f573fSAndroid Build Coastguard Worker
66*1b3f573fSAndroid Build Coastguard Worker    def test_issue_8559_crash
67*1b3f573fSAndroid Build Coastguard Worker      msg = TestMessage.new
68*1b3f573fSAndroid Build Coastguard Worker      msg.repeated_int32 = ::Google::Protobuf::RepeatedField.new(:int32, [1, 2, 3])
69*1b3f573fSAndroid Build Coastguard Worker
70*1b3f573fSAndroid Build Coastguard Worker      # https://github.com/jruby/jruby/issues/6818 was fixed in JRuby 9.3.0.0
71*1b3f573fSAndroid Build Coastguard Worker      if cruby_or_jruby_9_3_or_higher?
72*1b3f573fSAndroid Build Coastguard Worker        GC.start(full_mark: true, immediate_sweep: true)
73*1b3f573fSAndroid Build Coastguard Worker      end
74*1b3f573fSAndroid Build Coastguard Worker      TestMessage.encode(msg)
75*1b3f573fSAndroid Build Coastguard Worker    end
76*1b3f573fSAndroid Build Coastguard Worker
77*1b3f573fSAndroid Build Coastguard Worker    def test_issue_9440
78*1b3f573fSAndroid Build Coastguard Worker      msg = HelloRequest.new
79*1b3f573fSAndroid Build Coastguard Worker      msg.id = 8
80*1b3f573fSAndroid Build Coastguard Worker      assert_equal 8, msg.id
81*1b3f573fSAndroid Build Coastguard Worker      msg.version = '1'
82*1b3f573fSAndroid Build Coastguard Worker      assert_equal 8, msg.id
83*1b3f573fSAndroid Build Coastguard Worker    end
84*1b3f573fSAndroid Build Coastguard Worker
85*1b3f573fSAndroid Build Coastguard Worker    def test_issue_9507
86*1b3f573fSAndroid Build Coastguard Worker      pool = Google::Protobuf::DescriptorPool.new
87*1b3f573fSAndroid Build Coastguard Worker      pool.build do
88*1b3f573fSAndroid Build Coastguard Worker        add_message "NpeMessage" do
89*1b3f573fSAndroid Build Coastguard Worker          optional :type, :enum, 1, "TestEnum"
90*1b3f573fSAndroid Build Coastguard Worker          optional :other, :string, 2
91*1b3f573fSAndroid Build Coastguard Worker        end
92*1b3f573fSAndroid Build Coastguard Worker        add_enum "TestEnum" do
93*1b3f573fSAndroid Build Coastguard Worker          value :Something, 0
94*1b3f573fSAndroid Build Coastguard Worker        end
95*1b3f573fSAndroid Build Coastguard Worker      end
96*1b3f573fSAndroid Build Coastguard Worker
97*1b3f573fSAndroid Build Coastguard Worker      msgclass = pool.lookup("NpeMessage").msgclass
98*1b3f573fSAndroid Build Coastguard Worker
99*1b3f573fSAndroid Build Coastguard Worker      m = msgclass.new(
100*1b3f573fSAndroid Build Coastguard Worker        other: "foo"      # must be set, but can be blank
101*1b3f573fSAndroid Build Coastguard Worker      )
102*1b3f573fSAndroid Build Coastguard Worker
103*1b3f573fSAndroid Build Coastguard Worker      begin
104*1b3f573fSAndroid Build Coastguard Worker        encoded = msgclass.encode(m)
105*1b3f573fSAndroid Build Coastguard Worker      rescue java.lang.NullPointerException
106*1b3f573fSAndroid Build Coastguard Worker        flunk "NPE rescued"
107*1b3f573fSAndroid Build Coastguard Worker      end
108*1b3f573fSAndroid Build Coastguard Worker      decoded = msgclass.decode(encoded)
109*1b3f573fSAndroid Build Coastguard Worker      decoded.inspect
110*1b3f573fSAndroid Build Coastguard Worker      decoded.to_proto
111*1b3f573fSAndroid Build Coastguard Worker    end
112*1b3f573fSAndroid Build Coastguard Worker
113*1b3f573fSAndroid Build Coastguard Worker    def test_has_field
114*1b3f573fSAndroid Build Coastguard Worker      m = TestSingularFields.new
115*1b3f573fSAndroid Build Coastguard Worker      assert !m.has_singular_msg?
116*1b3f573fSAndroid Build Coastguard Worker      m.singular_msg = TestMessage2.new
117*1b3f573fSAndroid Build Coastguard Worker      assert m.has_singular_msg?
118*1b3f573fSAndroid Build Coastguard Worker      assert TestSingularFields.descriptor.lookup('singular_msg').has?(m)
119*1b3f573fSAndroid Build Coastguard Worker
120*1b3f573fSAndroid Build Coastguard Worker      m = OneofMessage.new
121*1b3f573fSAndroid Build Coastguard Worker      assert !m.has_my_oneof?
122*1b3f573fSAndroid Build Coastguard Worker      m.a = "foo"
123*1b3f573fSAndroid Build Coastguard Worker      assert m.has_my_oneof?
124*1b3f573fSAndroid Build Coastguard Worker      assert_raise NoMethodError do
125*1b3f573fSAndroid Build Coastguard Worker        m.has_a?
126*1b3f573fSAndroid Build Coastguard Worker      end
127*1b3f573fSAndroid Build Coastguard Worker      assert_true OneofMessage.descriptor.lookup('a').has?(m)
128*1b3f573fSAndroid Build Coastguard Worker
129*1b3f573fSAndroid Build Coastguard Worker      m = TestSingularFields.new
130*1b3f573fSAndroid Build Coastguard Worker      assert_raise NoMethodError do
131*1b3f573fSAndroid Build Coastguard Worker        m.has_singular_int32?
132*1b3f573fSAndroid Build Coastguard Worker      end
133*1b3f573fSAndroid Build Coastguard Worker      assert_raise ArgumentError do
134*1b3f573fSAndroid Build Coastguard Worker        TestSingularFields.descriptor.lookup('singular_int32').has?(m)
135*1b3f573fSAndroid Build Coastguard Worker      end
136*1b3f573fSAndroid Build Coastguard Worker
137*1b3f573fSAndroid Build Coastguard Worker      assert_raise NoMethodError do
138*1b3f573fSAndroid Build Coastguard Worker        m.has_singular_string?
139*1b3f573fSAndroid Build Coastguard Worker      end
140*1b3f573fSAndroid Build Coastguard Worker      assert_raise ArgumentError do
141*1b3f573fSAndroid Build Coastguard Worker        TestSingularFields.descriptor.lookup('singular_string').has?(m)
142*1b3f573fSAndroid Build Coastguard Worker      end
143*1b3f573fSAndroid Build Coastguard Worker
144*1b3f573fSAndroid Build Coastguard Worker      assert_raise NoMethodError do
145*1b3f573fSAndroid Build Coastguard Worker        m.has_singular_bool?
146*1b3f573fSAndroid Build Coastguard Worker      end
147*1b3f573fSAndroid Build Coastguard Worker      assert_raise ArgumentError do
148*1b3f573fSAndroid Build Coastguard Worker        TestSingularFields.descriptor.lookup('singular_bool').has?(m)
149*1b3f573fSAndroid Build Coastguard Worker      end
150*1b3f573fSAndroid Build Coastguard Worker
151*1b3f573fSAndroid Build Coastguard Worker      m = TestMessage.new
152*1b3f573fSAndroid Build Coastguard Worker      assert_raise NoMethodError do
153*1b3f573fSAndroid Build Coastguard Worker        m.has_repeated_msg?
154*1b3f573fSAndroid Build Coastguard Worker      end
155*1b3f573fSAndroid Build Coastguard Worker      assert_raise ArgumentError do
156*1b3f573fSAndroid Build Coastguard Worker        TestMessage.descriptor.lookup('repeated_msg').has?(m)
157*1b3f573fSAndroid Build Coastguard Worker      end
158*1b3f573fSAndroid Build Coastguard Worker    end
159*1b3f573fSAndroid Build Coastguard Worker
160*1b3f573fSAndroid Build Coastguard Worker    def test_no_presence
161*1b3f573fSAndroid Build Coastguard Worker      m = TestSingularFields.new
162*1b3f573fSAndroid Build Coastguard Worker
163*1b3f573fSAndroid Build Coastguard Worker      # Explicitly setting to zero does not cause anything to be serialized.
164*1b3f573fSAndroid Build Coastguard Worker      m.singular_int32 = 0
165*1b3f573fSAndroid Build Coastguard Worker      assert_equal "", TestSingularFields.encode(m)
166*1b3f573fSAndroid Build Coastguard Worker
167*1b3f573fSAndroid Build Coastguard Worker      # Explicitly setting to a non-zero value *does* cause serialization.
168*1b3f573fSAndroid Build Coastguard Worker      m.singular_int32 = 1
169*1b3f573fSAndroid Build Coastguard Worker      assert_not_equal "", TestSingularFields.encode(m)
170*1b3f573fSAndroid Build Coastguard Worker
171*1b3f573fSAndroid Build Coastguard Worker      m.singular_int32 = 0
172*1b3f573fSAndroid Build Coastguard Worker      assert_equal "", TestSingularFields.encode(m)
173*1b3f573fSAndroid Build Coastguard Worker    end
174*1b3f573fSAndroid Build Coastguard Worker
175*1b3f573fSAndroid Build Coastguard Worker    def test_set_clear_defaults
176*1b3f573fSAndroid Build Coastguard Worker      m = TestSingularFields.new
177*1b3f573fSAndroid Build Coastguard Worker
178*1b3f573fSAndroid Build Coastguard Worker      m.singular_int32 = -42
179*1b3f573fSAndroid Build Coastguard Worker      assert_equal( -42, m.singular_int32 )
180*1b3f573fSAndroid Build Coastguard Worker      m.clear_singular_int32
181*1b3f573fSAndroid Build Coastguard Worker      assert_equal 0, m.singular_int32
182*1b3f573fSAndroid Build Coastguard Worker
183*1b3f573fSAndroid Build Coastguard Worker      m.singular_int32 = 50
184*1b3f573fSAndroid Build Coastguard Worker      assert_equal 50, m.singular_int32
185*1b3f573fSAndroid Build Coastguard Worker      TestSingularFields.descriptor.lookup('singular_int32').clear(m)
186*1b3f573fSAndroid Build Coastguard Worker      assert_equal 0, m.singular_int32
187*1b3f573fSAndroid Build Coastguard Worker
188*1b3f573fSAndroid Build Coastguard Worker      m.singular_string = "foo bar"
189*1b3f573fSAndroid Build Coastguard Worker      assert_equal "foo bar", m.singular_string
190*1b3f573fSAndroid Build Coastguard Worker      m.clear_singular_string
191*1b3f573fSAndroid Build Coastguard Worker      assert_equal "", m.singular_string
192*1b3f573fSAndroid Build Coastguard Worker
193*1b3f573fSAndroid Build Coastguard Worker      m.singular_string = "foo"
194*1b3f573fSAndroid Build Coastguard Worker      assert_equal "foo", m.singular_string
195*1b3f573fSAndroid Build Coastguard Worker      TestSingularFields.descriptor.lookup('singular_string').clear(m)
196*1b3f573fSAndroid Build Coastguard Worker      assert_equal "", m.singular_string
197*1b3f573fSAndroid Build Coastguard Worker
198*1b3f573fSAndroid Build Coastguard Worker      m.singular_msg = TestMessage2.new(:foo => 42)
199*1b3f573fSAndroid Build Coastguard Worker      assert_equal TestMessage2.new(:foo => 42), m.singular_msg
200*1b3f573fSAndroid Build Coastguard Worker      assert m.has_singular_msg?
201*1b3f573fSAndroid Build Coastguard Worker      m.clear_singular_msg
202*1b3f573fSAndroid Build Coastguard Worker      assert_equal nil, m.singular_msg
203*1b3f573fSAndroid Build Coastguard Worker      assert !m.has_singular_msg?
204*1b3f573fSAndroid Build Coastguard Worker
205*1b3f573fSAndroid Build Coastguard Worker      m.singular_msg = TestMessage2.new(:foo => 42)
206*1b3f573fSAndroid Build Coastguard Worker      assert_equal TestMessage2.new(:foo => 42), m.singular_msg
207*1b3f573fSAndroid Build Coastguard Worker      TestSingularFields.descriptor.lookup('singular_msg').clear(m)
208*1b3f573fSAndroid Build Coastguard Worker      assert_equal nil, m.singular_msg
209*1b3f573fSAndroid Build Coastguard Worker    end
210*1b3f573fSAndroid Build Coastguard Worker
211*1b3f573fSAndroid Build Coastguard Worker    def test_import_proto2
212*1b3f573fSAndroid Build Coastguard Worker      m = TestMessage.new
213*1b3f573fSAndroid Build Coastguard Worker      assert !m.has_optional_proto2_submessage?
214*1b3f573fSAndroid Build Coastguard Worker      m.optional_proto2_submessage = ::FooBar::Proto2::TestImportedMessage.new
215*1b3f573fSAndroid Build Coastguard Worker      assert m.has_optional_proto2_submessage?
216*1b3f573fSAndroid Build Coastguard Worker      assert TestMessage.descriptor.lookup('optional_proto2_submessage').has?(m)
217*1b3f573fSAndroid Build Coastguard Worker
218*1b3f573fSAndroid Build Coastguard Worker      m.clear_optional_proto2_submessage
219*1b3f573fSAndroid Build Coastguard Worker      assert !m.has_optional_proto2_submessage?
220*1b3f573fSAndroid Build Coastguard Worker    end
221*1b3f573fSAndroid Build Coastguard Worker
222*1b3f573fSAndroid Build Coastguard Worker    def test_clear_repeated_fields
223*1b3f573fSAndroid Build Coastguard Worker      m = TestMessage.new
224*1b3f573fSAndroid Build Coastguard Worker
225*1b3f573fSAndroid Build Coastguard Worker      m.repeated_int32.push(1)
226*1b3f573fSAndroid Build Coastguard Worker      assert_equal [1], m.repeated_int32
227*1b3f573fSAndroid Build Coastguard Worker      m.clear_repeated_int32
228*1b3f573fSAndroid Build Coastguard Worker      assert_equal [], m.repeated_int32
229*1b3f573fSAndroid Build Coastguard Worker
230*1b3f573fSAndroid Build Coastguard Worker      m.repeated_int32.push(1)
231*1b3f573fSAndroid Build Coastguard Worker      assert_equal [1], m.repeated_int32
232*1b3f573fSAndroid Build Coastguard Worker      TestMessage.descriptor.lookup('repeated_int32').clear(m)
233*1b3f573fSAndroid Build Coastguard Worker      assert_equal [], m.repeated_int32
234*1b3f573fSAndroid Build Coastguard Worker
235*1b3f573fSAndroid Build Coastguard Worker      m = OneofMessage.new
236*1b3f573fSAndroid Build Coastguard Worker      m.a = "foo"
237*1b3f573fSAndroid Build Coastguard Worker      assert_equal "foo", m.a
238*1b3f573fSAndroid Build Coastguard Worker      assert m.has_my_oneof?
239*1b3f573fSAndroid Build Coastguard Worker      assert_equal :a, m.my_oneof
240*1b3f573fSAndroid Build Coastguard Worker      m.clear_a
241*1b3f573fSAndroid Build Coastguard Worker      assert !m.has_my_oneof?
242*1b3f573fSAndroid Build Coastguard Worker
243*1b3f573fSAndroid Build Coastguard Worker      m.a = "foobar"
244*1b3f573fSAndroid Build Coastguard Worker      assert m.has_my_oneof?
245*1b3f573fSAndroid Build Coastguard Worker      m.clear_my_oneof
246*1b3f573fSAndroid Build Coastguard Worker      assert !m.has_my_oneof?
247*1b3f573fSAndroid Build Coastguard Worker
248*1b3f573fSAndroid Build Coastguard Worker      m.a = "bar"
249*1b3f573fSAndroid Build Coastguard Worker      assert_equal "bar", m.a
250*1b3f573fSAndroid Build Coastguard Worker      assert m.has_my_oneof?
251*1b3f573fSAndroid Build Coastguard Worker      OneofMessage.descriptor.lookup('a').clear(m)
252*1b3f573fSAndroid Build Coastguard Worker      assert !m.has_my_oneof?
253*1b3f573fSAndroid Build Coastguard Worker    end
254*1b3f573fSAndroid Build Coastguard Worker
255*1b3f573fSAndroid Build Coastguard Worker    def test_initialization_map_errors
256*1b3f573fSAndroid Build Coastguard Worker      e = assert_raise ArgumentError do
257*1b3f573fSAndroid Build Coastguard Worker        TestMessage.new(:hello => "world")
258*1b3f573fSAndroid Build Coastguard Worker      end
259*1b3f573fSAndroid Build Coastguard Worker      assert_match(/hello/, e.message)
260*1b3f573fSAndroid Build Coastguard Worker
261*1b3f573fSAndroid Build Coastguard Worker      e = assert_raise ArgumentError do
262*1b3f573fSAndroid Build Coastguard Worker        MapMessage.new(:map_string_int32 => "hello")
263*1b3f573fSAndroid Build Coastguard Worker      end
264*1b3f573fSAndroid Build Coastguard Worker      assert_equal e.message, "Expected Hash object as initializer value for map field 'map_string_int32' (given String)."
265*1b3f573fSAndroid Build Coastguard Worker
266*1b3f573fSAndroid Build Coastguard Worker      e = assert_raise ArgumentError do
267*1b3f573fSAndroid Build Coastguard Worker        TestMessage.new(:repeated_uint32 => "hello")
268*1b3f573fSAndroid Build Coastguard Worker      end
269*1b3f573fSAndroid Build Coastguard Worker      assert_equal e.message, "Expected array as initializer value for repeated field 'repeated_uint32' (given String)."
270*1b3f573fSAndroid Build Coastguard Worker    end
271*1b3f573fSAndroid Build Coastguard Worker
272*1b3f573fSAndroid Build Coastguard Worker    def test_map_field
273*1b3f573fSAndroid Build Coastguard Worker      m = MapMessage.new
274*1b3f573fSAndroid Build Coastguard Worker      assert m.map_string_int32 == {}
275*1b3f573fSAndroid Build Coastguard Worker      assert m.map_string_msg == {}
276*1b3f573fSAndroid Build Coastguard Worker
277*1b3f573fSAndroid Build Coastguard Worker      m = MapMessage.new(
278*1b3f573fSAndroid Build Coastguard Worker        :map_string_int32 => {"a" => 1, "b" => 2},
279*1b3f573fSAndroid Build Coastguard Worker        :map_string_msg => {"a" => TestMessage2.new(:foo => 1),
280*1b3f573fSAndroid Build Coastguard Worker                            "b" => TestMessage2.new(:foo => 2)},
281*1b3f573fSAndroid Build Coastguard Worker        :map_string_enum => {"a" => :A, "b" => :B})
282*1b3f573fSAndroid Build Coastguard Worker      assert m.map_string_int32.keys.sort == ["a", "b"]
283*1b3f573fSAndroid Build Coastguard Worker      assert m.map_string_int32["a"] == 1
284*1b3f573fSAndroid Build Coastguard Worker      assert m.map_string_msg["b"].foo == 2
285*1b3f573fSAndroid Build Coastguard Worker      assert m.map_string_enum["a"] == :A
286*1b3f573fSAndroid Build Coastguard Worker
287*1b3f573fSAndroid Build Coastguard Worker      m.map_string_int32["c"] = 3
288*1b3f573fSAndroid Build Coastguard Worker      assert m.map_string_int32["c"] == 3
289*1b3f573fSAndroid Build Coastguard Worker      m.map_string_msg["c"] = TestMessage2.new(:foo => 3)
290*1b3f573fSAndroid Build Coastguard Worker      assert m.map_string_msg["c"] == TestMessage2.new(:foo => 3)
291*1b3f573fSAndroid Build Coastguard Worker      m.map_string_msg.delete("b")
292*1b3f573fSAndroid Build Coastguard Worker      m.map_string_msg.delete("c")
293*1b3f573fSAndroid Build Coastguard Worker      assert m.map_string_msg == { "a" => TestMessage2.new(:foo => 1) }
294*1b3f573fSAndroid Build Coastguard Worker
295*1b3f573fSAndroid Build Coastguard Worker      assert_raise Google::Protobuf::TypeError do
296*1b3f573fSAndroid Build Coastguard Worker        m.map_string_msg["e"] = TestMessage.new # wrong value type
297*1b3f573fSAndroid Build Coastguard Worker      end
298*1b3f573fSAndroid Build Coastguard Worker      # ensure nothing was added by the above
299*1b3f573fSAndroid Build Coastguard Worker      assert m.map_string_msg == { "a" => TestMessage2.new(:foo => 1) }
300*1b3f573fSAndroid Build Coastguard Worker
301*1b3f573fSAndroid Build Coastguard Worker      m.map_string_int32 = Google::Protobuf::Map.new(:string, :int32)
302*1b3f573fSAndroid Build Coastguard Worker      assert_raise Google::Protobuf::TypeError do
303*1b3f573fSAndroid Build Coastguard Worker        m.map_string_int32 = Google::Protobuf::Map.new(:string, :int64)
304*1b3f573fSAndroid Build Coastguard Worker      end
305*1b3f573fSAndroid Build Coastguard Worker      assert_raise Google::Protobuf::TypeError do
306*1b3f573fSAndroid Build Coastguard Worker        m.map_string_int32 = {}
307*1b3f573fSAndroid Build Coastguard Worker      end
308*1b3f573fSAndroid Build Coastguard Worker
309*1b3f573fSAndroid Build Coastguard Worker      assert_raise Google::Protobuf::TypeError do
310*1b3f573fSAndroid Build Coastguard Worker        m = MapMessage.new(:map_string_int32 => { 1 => "I am not a number" })
311*1b3f573fSAndroid Build Coastguard Worker      end
312*1b3f573fSAndroid Build Coastguard Worker    end
313*1b3f573fSAndroid Build Coastguard Worker
314*1b3f573fSAndroid Build Coastguard Worker    def test_map_field_with_symbol
315*1b3f573fSAndroid Build Coastguard Worker      m = MapMessage.new
316*1b3f573fSAndroid Build Coastguard Worker      assert m.map_string_int32 == {}
317*1b3f573fSAndroid Build Coastguard Worker      assert m.map_string_msg == {}
318*1b3f573fSAndroid Build Coastguard Worker
319*1b3f573fSAndroid Build Coastguard Worker      m = MapMessage.new(
320*1b3f573fSAndroid Build Coastguard Worker        :map_string_int32 => {a: 1, "b" => 2},
321*1b3f573fSAndroid Build Coastguard Worker        :map_string_msg => {a: TestMessage2.new(:foo => 1),
322*1b3f573fSAndroid Build Coastguard Worker                            b: TestMessage2.new(:foo => 10)})
323*1b3f573fSAndroid Build Coastguard Worker      assert_equal 1, m.map_string_int32[:a]
324*1b3f573fSAndroid Build Coastguard Worker      assert_equal 2, m.map_string_int32[:b]
325*1b3f573fSAndroid Build Coastguard Worker      assert_equal 10, m.map_string_msg[:b].foo
326*1b3f573fSAndroid Build Coastguard Worker    end
327*1b3f573fSAndroid Build Coastguard Worker
328*1b3f573fSAndroid Build Coastguard Worker    def test_map_inspect
329*1b3f573fSAndroid Build Coastguard Worker      m = MapMessage.new(
330*1b3f573fSAndroid Build Coastguard Worker        :map_string_int32 => {"a" => 1, "b" => 2},
331*1b3f573fSAndroid Build Coastguard Worker        :map_string_msg => {"a" => TestMessage2.new(:foo => 1),
332*1b3f573fSAndroid Build Coastguard Worker                            "b" => TestMessage2.new(:foo => 2)},
333*1b3f573fSAndroid Build Coastguard Worker        :map_string_enum => {"a" => :A, "b" => :B})
334*1b3f573fSAndroid Build Coastguard Worker
335*1b3f573fSAndroid Build Coastguard Worker      # JRuby doesn't keep consistent ordering so check for either version
336*1b3f573fSAndroid Build Coastguard Worker      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}>"
337*1b3f573fSAndroid Build Coastguard Worker      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}>"
338*1b3f573fSAndroid Build Coastguard Worker      inspect_result = m.inspect
339*1b3f573fSAndroid Build Coastguard Worker      assert expected_a == inspect_result || expected_b == inspect_result, "Incorrect inspect result: #{inspect_result}"
340*1b3f573fSAndroid Build Coastguard Worker    end
341*1b3f573fSAndroid Build Coastguard Worker
342*1b3f573fSAndroid Build Coastguard Worker    def test_map_corruption
343*1b3f573fSAndroid Build Coastguard Worker      # This pattern led to a crash in a previous version of upb/protobuf.
344*1b3f573fSAndroid Build Coastguard Worker      m = MapMessage.new(map_string_int32: { "aaa" => 1 })
345*1b3f573fSAndroid Build Coastguard Worker      m.map_string_int32['podid'] = 2
346*1b3f573fSAndroid Build Coastguard Worker      m.map_string_int32['aaa'] = 3
347*1b3f573fSAndroid Build Coastguard Worker    end
348*1b3f573fSAndroid Build Coastguard Worker
349*1b3f573fSAndroid Build Coastguard Worker    def test_map_wrappers
350*1b3f573fSAndroid Build Coastguard Worker      run_asserts = ->(m) {
351*1b3f573fSAndroid Build Coastguard Worker        assert_equal 2.0, m.map_double[0].value
352*1b3f573fSAndroid Build Coastguard Worker        assert_equal 4.0, m.map_float[0].value
353*1b3f573fSAndroid Build Coastguard Worker        assert_equal 3, m.map_int32[0].value
354*1b3f573fSAndroid Build Coastguard Worker        assert_equal 4, m.map_int64[0].value
355*1b3f573fSAndroid Build Coastguard Worker        assert_equal 5, m.map_uint32[0].value
356*1b3f573fSAndroid Build Coastguard Worker        assert_equal 6, m.map_uint64[0].value
357*1b3f573fSAndroid Build Coastguard Worker        assert_equal true, m.map_bool[0].value
358*1b3f573fSAndroid Build Coastguard Worker        assert_equal 'str', m.map_string[0].value
359*1b3f573fSAndroid Build Coastguard Worker        assert_equal 'fun', m.map_bytes[0].value
360*1b3f573fSAndroid Build Coastguard Worker      }
361*1b3f573fSAndroid Build Coastguard Worker
362*1b3f573fSAndroid Build Coastguard Worker      m = proto_module::Wrapper.new(
363*1b3f573fSAndroid Build Coastguard Worker        map_double: {0 => Google::Protobuf::DoubleValue.new(value: 2.0)},
364*1b3f573fSAndroid Build Coastguard Worker        map_float: {0 => Google::Protobuf::FloatValue.new(value: 4.0)},
365*1b3f573fSAndroid Build Coastguard Worker        map_int32: {0 => Google::Protobuf::Int32Value.new(value: 3)},
366*1b3f573fSAndroid Build Coastguard Worker        map_int64: {0 => Google::Protobuf::Int64Value.new(value: 4)},
367*1b3f573fSAndroid Build Coastguard Worker        map_uint32: {0 => Google::Protobuf::UInt32Value.new(value: 5)},
368*1b3f573fSAndroid Build Coastguard Worker        map_uint64: {0 => Google::Protobuf::UInt64Value.new(value: 6)},
369*1b3f573fSAndroid Build Coastguard Worker        map_bool: {0 => Google::Protobuf::BoolValue.new(value: true)},
370*1b3f573fSAndroid Build Coastguard Worker        map_string: {0 => Google::Protobuf::StringValue.new(value: 'str')},
371*1b3f573fSAndroid Build Coastguard Worker        map_bytes: {0 => Google::Protobuf::BytesValue.new(value: 'fun')},
372*1b3f573fSAndroid Build Coastguard Worker      )
373*1b3f573fSAndroid Build Coastguard Worker
374*1b3f573fSAndroid Build Coastguard Worker      run_asserts.call(m)
375*1b3f573fSAndroid Build Coastguard Worker      serialized = proto_module::Wrapper::encode(m)
376*1b3f573fSAndroid Build Coastguard Worker      m2 = proto_module::Wrapper::decode(serialized)
377*1b3f573fSAndroid Build Coastguard Worker      run_asserts.call(m2)
378*1b3f573fSAndroid Build Coastguard Worker
379*1b3f573fSAndroid Build Coastguard Worker      # Test the case where we are serializing directly from the parsed form
380*1b3f573fSAndroid Build Coastguard Worker      # (before anything lazy is materialized).
381*1b3f573fSAndroid Build Coastguard Worker      m3 = proto_module::Wrapper::decode(serialized)
382*1b3f573fSAndroid Build Coastguard Worker      serialized2 = proto_module::Wrapper::encode(m3)
383*1b3f573fSAndroid Build Coastguard Worker      m4 = proto_module::Wrapper::decode(serialized2)
384*1b3f573fSAndroid Build Coastguard Worker      run_asserts.call(m4)
385*1b3f573fSAndroid Build Coastguard Worker
386*1b3f573fSAndroid Build Coastguard Worker      # Test that the lazy form compares equal to the expanded form.
387*1b3f573fSAndroid Build Coastguard Worker      m5 = proto_module::Wrapper::decode(serialized2)
388*1b3f573fSAndroid Build Coastguard Worker      assert_equal m5, m
389*1b3f573fSAndroid Build Coastguard Worker    end
390*1b3f573fSAndroid Build Coastguard Worker
391*1b3f573fSAndroid Build Coastguard Worker    def test_map_wrappers_with_default_values
392*1b3f573fSAndroid Build Coastguard Worker      run_asserts = ->(m) {
393*1b3f573fSAndroid Build Coastguard Worker        assert_equal 0.0, m.map_double[0].value
394*1b3f573fSAndroid Build Coastguard Worker        assert_equal 0.0, m.map_float[0].value
395*1b3f573fSAndroid Build Coastguard Worker        assert_equal 0, m.map_int32[0].value
396*1b3f573fSAndroid Build Coastguard Worker        assert_equal 0, m.map_int64[0].value
397*1b3f573fSAndroid Build Coastguard Worker        assert_equal 0, m.map_uint32[0].value
398*1b3f573fSAndroid Build Coastguard Worker        assert_equal 0, m.map_uint64[0].value
399*1b3f573fSAndroid Build Coastguard Worker        assert_equal false, m.map_bool[0].value
400*1b3f573fSAndroid Build Coastguard Worker        assert_equal '', m.map_string[0].value
401*1b3f573fSAndroid Build Coastguard Worker        assert_equal '', m.map_bytes[0].value
402*1b3f573fSAndroid Build Coastguard Worker      }
403*1b3f573fSAndroid Build Coastguard Worker
404*1b3f573fSAndroid Build Coastguard Worker      m = proto_module::Wrapper.new(
405*1b3f573fSAndroid Build Coastguard Worker        map_double: {0 => Google::Protobuf::DoubleValue.new(value: 0.0)},
406*1b3f573fSAndroid Build Coastguard Worker        map_float: {0 => Google::Protobuf::FloatValue.new(value: 0.0)},
407*1b3f573fSAndroid Build Coastguard Worker        map_int32: {0 => Google::Protobuf::Int32Value.new(value: 0)},
408*1b3f573fSAndroid Build Coastguard Worker        map_int64: {0 => Google::Protobuf::Int64Value.new(value: 0)},
409*1b3f573fSAndroid Build Coastguard Worker        map_uint32: {0 => Google::Protobuf::UInt32Value.new(value: 0)},
410*1b3f573fSAndroid Build Coastguard Worker        map_uint64: {0 => Google::Protobuf::UInt64Value.new(value: 0)},
411*1b3f573fSAndroid Build Coastguard Worker        map_bool: {0 => Google::Protobuf::BoolValue.new(value: false)},
412*1b3f573fSAndroid Build Coastguard Worker        map_string: {0 => Google::Protobuf::StringValue.new(value: '')},
413*1b3f573fSAndroid Build Coastguard Worker        map_bytes: {0 => Google::Protobuf::BytesValue.new(value: '')},
414*1b3f573fSAndroid Build Coastguard Worker      )
415*1b3f573fSAndroid Build Coastguard Worker
416*1b3f573fSAndroid Build Coastguard Worker      run_asserts.call(m)
417*1b3f573fSAndroid Build Coastguard Worker      serialized = proto_module::Wrapper::encode(m)
418*1b3f573fSAndroid Build Coastguard Worker      m2 = proto_module::Wrapper::decode(serialized)
419*1b3f573fSAndroid Build Coastguard Worker      run_asserts.call(m2)
420*1b3f573fSAndroid Build Coastguard Worker
421*1b3f573fSAndroid Build Coastguard Worker      # Test the case where we are serializing directly from the parsed form
422*1b3f573fSAndroid Build Coastguard Worker      # (before anything lazy is materialized).
423*1b3f573fSAndroid Build Coastguard Worker      m3 = proto_module::Wrapper::decode(serialized)
424*1b3f573fSAndroid Build Coastguard Worker      serialized2 = proto_module::Wrapper::encode(m3)
425*1b3f573fSAndroid Build Coastguard Worker      m4 = proto_module::Wrapper::decode(serialized2)
426*1b3f573fSAndroid Build Coastguard Worker      run_asserts.call(m4)
427*1b3f573fSAndroid Build Coastguard Worker
428*1b3f573fSAndroid Build Coastguard Worker      # Test that the lazy form compares equal to the expanded form.
429*1b3f573fSAndroid Build Coastguard Worker      m5 = proto_module::Wrapper::decode(serialized2)
430*1b3f573fSAndroid Build Coastguard Worker      assert_equal m5, m
431*1b3f573fSAndroid Build Coastguard Worker    end
432*1b3f573fSAndroid Build Coastguard Worker
433*1b3f573fSAndroid Build Coastguard Worker    def test_map_wrappers_with_no_value
434*1b3f573fSAndroid Build Coastguard Worker      run_asserts = ->(m) {
435*1b3f573fSAndroid Build Coastguard Worker        assert_equal 0.0, m.map_double[0].value
436*1b3f573fSAndroid Build Coastguard Worker        assert_equal 0.0, m.map_float[0].value
437*1b3f573fSAndroid Build Coastguard Worker        assert_equal 0, m.map_int32[0].value
438*1b3f573fSAndroid Build Coastguard Worker        assert_equal 0, m.map_int64[0].value
439*1b3f573fSAndroid Build Coastguard Worker        assert_equal 0, m.map_uint32[0].value
440*1b3f573fSAndroid Build Coastguard Worker        assert_equal 0, m.map_uint64[0].value
441*1b3f573fSAndroid Build Coastguard Worker        assert_equal false, m.map_bool[0].value
442*1b3f573fSAndroid Build Coastguard Worker        assert_equal '', m.map_string[0].value
443*1b3f573fSAndroid Build Coastguard Worker        assert_equal '', m.map_bytes[0].value
444*1b3f573fSAndroid Build Coastguard Worker      }
445*1b3f573fSAndroid Build Coastguard Worker
446*1b3f573fSAndroid Build Coastguard Worker      m = proto_module::Wrapper.new(
447*1b3f573fSAndroid Build Coastguard Worker        map_double: {0 => Google::Protobuf::DoubleValue.new()},
448*1b3f573fSAndroid Build Coastguard Worker        map_float: {0 => Google::Protobuf::FloatValue.new()},
449*1b3f573fSAndroid Build Coastguard Worker        map_int32: {0 => Google::Protobuf::Int32Value.new()},
450*1b3f573fSAndroid Build Coastguard Worker        map_int64: {0 => Google::Protobuf::Int64Value.new()},
451*1b3f573fSAndroid Build Coastguard Worker        map_uint32: {0 => Google::Protobuf::UInt32Value.new()},
452*1b3f573fSAndroid Build Coastguard Worker        map_uint64: {0 => Google::Protobuf::UInt64Value.new()},
453*1b3f573fSAndroid Build Coastguard Worker        map_bool: {0 => Google::Protobuf::BoolValue.new()},
454*1b3f573fSAndroid Build Coastguard Worker        map_string: {0 => Google::Protobuf::StringValue.new()},
455*1b3f573fSAndroid Build Coastguard Worker        map_bytes: {0 => Google::Protobuf::BytesValue.new()},
456*1b3f573fSAndroid Build Coastguard Worker      )
457*1b3f573fSAndroid Build Coastguard Worker      run_asserts.call(m)
458*1b3f573fSAndroid Build Coastguard Worker
459*1b3f573fSAndroid Build Coastguard Worker      serialized = proto_module::Wrapper::encode(m)
460*1b3f573fSAndroid Build Coastguard Worker      m2 = proto_module::Wrapper::decode(serialized)
461*1b3f573fSAndroid Build Coastguard Worker      run_asserts.call(m2)
462*1b3f573fSAndroid Build Coastguard Worker
463*1b3f573fSAndroid Build Coastguard Worker      # Test the case where we are serializing directly from the parsed form
464*1b3f573fSAndroid Build Coastguard Worker      # (before anything lazy is materialized).
465*1b3f573fSAndroid Build Coastguard Worker      m3 = proto_module::Wrapper::decode(serialized)
466*1b3f573fSAndroid Build Coastguard Worker      serialized2 = proto_module::Wrapper::encode(m3)
467*1b3f573fSAndroid Build Coastguard Worker      m4 = proto_module::Wrapper::decode(serialized2)
468*1b3f573fSAndroid Build Coastguard Worker      run_asserts.call(m4)
469*1b3f573fSAndroid Build Coastguard Worker    end
470*1b3f573fSAndroid Build Coastguard Worker
471*1b3f573fSAndroid Build Coastguard Worker    def test_concurrent_decoding
472*1b3f573fSAndroid Build Coastguard Worker      o = Outer.new
473*1b3f573fSAndroid Build Coastguard Worker      o.items[0] = Inner.new
474*1b3f573fSAndroid Build Coastguard Worker      raw = Outer.encode(o)
475*1b3f573fSAndroid Build Coastguard Worker
476*1b3f573fSAndroid Build Coastguard Worker      thds = 2.times.map do
477*1b3f573fSAndroid Build Coastguard Worker        Thread.new do
478*1b3f573fSAndroid Build Coastguard Worker          100000.times do
479*1b3f573fSAndroid Build Coastguard Worker            assert_equal o, Outer.decode(raw)
480*1b3f573fSAndroid Build Coastguard Worker          end
481*1b3f573fSAndroid Build Coastguard Worker        end
482*1b3f573fSAndroid Build Coastguard Worker      end
483*1b3f573fSAndroid Build Coastguard Worker      thds.map(&:join)
484*1b3f573fSAndroid Build Coastguard Worker    end
485*1b3f573fSAndroid Build Coastguard Worker
486*1b3f573fSAndroid Build Coastguard Worker    def test_map_encode_decode
487*1b3f573fSAndroid Build Coastguard Worker      m = MapMessage.new(
488*1b3f573fSAndroid Build Coastguard Worker        :map_string_int32 => {"a" => 1, "b" => 2},
489*1b3f573fSAndroid Build Coastguard Worker        :map_string_msg => {"a" => TestMessage2.new(:foo => 1),
490*1b3f573fSAndroid Build Coastguard Worker                            "b" => TestMessage2.new(:foo => 2)},
491*1b3f573fSAndroid Build Coastguard Worker        :map_string_enum => {"a" => :A, "b" => :B})
492*1b3f573fSAndroid Build Coastguard Worker      m2 = MapMessage.decode(MapMessage.encode(m))
493*1b3f573fSAndroid Build Coastguard Worker      assert m == m2
494*1b3f573fSAndroid Build Coastguard Worker
495*1b3f573fSAndroid Build Coastguard Worker      m3 = MapMessageWireEquiv.decode(MapMessage.encode(m))
496*1b3f573fSAndroid Build Coastguard Worker      assert m3.map_string_int32.length == 2
497*1b3f573fSAndroid Build Coastguard Worker
498*1b3f573fSAndroid Build Coastguard Worker      kv = {}
499*1b3f573fSAndroid Build Coastguard Worker      m3.map_string_int32.map { |msg| kv[msg.key] = msg.value }
500*1b3f573fSAndroid Build Coastguard Worker      assert kv == {"a" => 1, "b" => 2}
501*1b3f573fSAndroid Build Coastguard Worker
502*1b3f573fSAndroid Build Coastguard Worker      kv = {}
503*1b3f573fSAndroid Build Coastguard Worker      m3.map_string_msg.map { |msg| kv[msg.key] = msg.value }
504*1b3f573fSAndroid Build Coastguard Worker      assert kv == {"a" => TestMessage2.new(:foo => 1),
505*1b3f573fSAndroid Build Coastguard Worker                    "b" => TestMessage2.new(:foo => 2)}
506*1b3f573fSAndroid Build Coastguard Worker    end
507*1b3f573fSAndroid Build Coastguard Worker
508*1b3f573fSAndroid Build Coastguard Worker    def test_protobuf_decode_json_ignore_unknown_fields
509*1b3f573fSAndroid Build Coastguard Worker      m = TestMessage.decode_json({
510*1b3f573fSAndroid Build Coastguard Worker        optional_string: "foo",
511*1b3f573fSAndroid Build Coastguard Worker        not_in_message: "some_value"
512*1b3f573fSAndroid Build Coastguard Worker      }.to_json, { ignore_unknown_fields: true })
513*1b3f573fSAndroid Build Coastguard Worker
514*1b3f573fSAndroid Build Coastguard Worker      assert_equal m.optional_string, "foo"
515*1b3f573fSAndroid Build Coastguard Worker      e = assert_raise Google::Protobuf::ParseError do
516*1b3f573fSAndroid Build Coastguard Worker        TestMessage.decode_json({ not_in_message: "some_value" }.to_json)
517*1b3f573fSAndroid Build Coastguard Worker      end
518*1b3f573fSAndroid Build Coastguard Worker      assert_match(/No such field: not_in_message/, e.message)
519*1b3f573fSAndroid Build Coastguard Worker    end
520*1b3f573fSAndroid Build Coastguard Worker
521*1b3f573fSAndroid Build Coastguard Worker    #def test_json_quoted_string
522*1b3f573fSAndroid Build Coastguard Worker    #  m = TestMessage.decode_json(%q(
523*1b3f573fSAndroid Build Coastguard Worker    #    "optionalInt64": "1",,
524*1b3f573fSAndroid Build Coastguard Worker    #  }))
525*1b3f573fSAndroid Build Coastguard Worker    #  puts(m)
526*1b3f573fSAndroid Build Coastguard Worker    #  assert_equal 1, m.optional_int32
527*1b3f573fSAndroid Build Coastguard Worker    #end
528*1b3f573fSAndroid Build Coastguard Worker
529*1b3f573fSAndroid Build Coastguard Worker    def test_to_h
530*1b3f573fSAndroid Build Coastguard Worker      m = TestMessage.new(:optional_bool => true, :optional_double => -10.100001, :optional_string => 'foo', :repeated_string => ['bar1', 'bar2'], :repeated_msg => [TestMessage2.new(:foo => 100)])
531*1b3f573fSAndroid Build Coastguard Worker      expected_result = {
532*1b3f573fSAndroid Build Coastguard Worker        :optional_bool=>true,
533*1b3f573fSAndroid Build Coastguard Worker        :optional_bytes=>"",
534*1b3f573fSAndroid Build Coastguard Worker        :optional_double=>-10.100001,
535*1b3f573fSAndroid Build Coastguard Worker        :optional_enum=>:Default,
536*1b3f573fSAndroid Build Coastguard Worker        :optional_float=>0.0,
537*1b3f573fSAndroid Build Coastguard Worker        :optional_int32=>0,
538*1b3f573fSAndroid Build Coastguard Worker        :optional_int64=>0,
539*1b3f573fSAndroid Build Coastguard Worker        :optional_msg=>nil,
540*1b3f573fSAndroid Build Coastguard Worker        :optional_msg2=>nil,
541*1b3f573fSAndroid Build Coastguard Worker        :optional_proto2_submessage=>nil,
542*1b3f573fSAndroid Build Coastguard Worker        :optional_string=>"foo",
543*1b3f573fSAndroid Build Coastguard Worker        :optional_uint32=>0,
544*1b3f573fSAndroid Build Coastguard Worker        :optional_uint64=>0,
545*1b3f573fSAndroid Build Coastguard Worker        :repeated_bool=>[],
546*1b3f573fSAndroid Build Coastguard Worker        :repeated_bytes=>[],
547*1b3f573fSAndroid Build Coastguard Worker        :repeated_double=>[],
548*1b3f573fSAndroid Build Coastguard Worker        :repeated_enum=>[],
549*1b3f573fSAndroid Build Coastguard Worker        :repeated_float=>[],
550*1b3f573fSAndroid Build Coastguard Worker        :repeated_int32=>[],
551*1b3f573fSAndroid Build Coastguard Worker        :repeated_int64=>[],
552*1b3f573fSAndroid Build Coastguard Worker        :repeated_msg=>[{:foo => 100}],
553*1b3f573fSAndroid Build Coastguard Worker        :repeated_string=>["bar1", "bar2"],
554*1b3f573fSAndroid Build Coastguard Worker        :repeated_uint32=>[],
555*1b3f573fSAndroid Build Coastguard Worker        :repeated_uint64=>[]
556*1b3f573fSAndroid Build Coastguard Worker      }
557*1b3f573fSAndroid Build Coastguard Worker      assert_equal expected_result, m.to_h
558*1b3f573fSAndroid Build Coastguard Worker
559*1b3f573fSAndroid Build Coastguard Worker      m = MapMessage.new(
560*1b3f573fSAndroid Build Coastguard Worker        :map_string_int32 => {"a" => 1, "b" => 2},
561*1b3f573fSAndroid Build Coastguard Worker        :map_string_msg => {"a" => TestMessage2.new(:foo => 1),
562*1b3f573fSAndroid Build Coastguard Worker                            "b" => TestMessage2.new(:foo => 2)},
563*1b3f573fSAndroid Build Coastguard Worker        :map_string_enum => {"a" => :A, "b" => :B})
564*1b3f573fSAndroid Build Coastguard Worker      expected_result = {
565*1b3f573fSAndroid Build Coastguard Worker        :map_string_int32 => {"a" => 1, "b" => 2},
566*1b3f573fSAndroid Build Coastguard Worker        :map_string_msg => {"a" => {:foo => 1}, "b" => {:foo => 2}},
567*1b3f573fSAndroid Build Coastguard Worker        :map_string_enum => {"a" => :A, "b" => :B}
568*1b3f573fSAndroid Build Coastguard Worker      }
569*1b3f573fSAndroid Build Coastguard Worker      assert_equal expected_result, m.to_h
570*1b3f573fSAndroid Build Coastguard Worker    end
571*1b3f573fSAndroid Build Coastguard Worker
572*1b3f573fSAndroid Build Coastguard Worker
573*1b3f573fSAndroid Build Coastguard Worker    def test_json_maps
574*1b3f573fSAndroid Build Coastguard Worker      m = MapMessage.new(:map_string_int32 => {"a" => 1})
575*1b3f573fSAndroid Build Coastguard Worker      expected = {mapStringInt32: {a: 1}, mapStringMsg: {}, mapStringEnum: {}}
576*1b3f573fSAndroid Build Coastguard Worker      expected_preserve = {map_string_int32: {a: 1}, map_string_msg: {}, map_string_enum: {}}
577*1b3f573fSAndroid Build Coastguard Worker      assert_equal JSON.parse(MapMessage.encode_json(m, :emit_defaults=>true), :symbolize_names => true), expected
578*1b3f573fSAndroid Build Coastguard Worker
579*1b3f573fSAndroid Build Coastguard Worker      json = MapMessage.encode_json(m, :preserve_proto_fieldnames => true, :emit_defaults=>true)
580*1b3f573fSAndroid Build Coastguard Worker      assert_equal JSON.parse(json, :symbolize_names => true), expected_preserve
581*1b3f573fSAndroid Build Coastguard Worker
582*1b3f573fSAndroid Build Coastguard Worker      m2 = MapMessage.decode_json(MapMessage.encode_json(m))
583*1b3f573fSAndroid Build Coastguard Worker      assert_equal m, m2
584*1b3f573fSAndroid Build Coastguard Worker    end
585*1b3f573fSAndroid Build Coastguard Worker
586*1b3f573fSAndroid Build Coastguard Worker    def test_json_maps_emit_defaults_submsg
587*1b3f573fSAndroid Build Coastguard Worker      m = MapMessage.new(:map_string_msg => {"a" => TestMessage2.new(foo: 0)})
588*1b3f573fSAndroid Build Coastguard Worker      expected = {mapStringInt32: {}, mapStringMsg: {a: {foo: 0}}, mapStringEnum: {}}
589*1b3f573fSAndroid Build Coastguard Worker
590*1b3f573fSAndroid Build Coastguard Worker      actual = MapMessage.encode_json(m, :emit_defaults => true)
591*1b3f573fSAndroid Build Coastguard Worker
592*1b3f573fSAndroid Build Coastguard Worker      assert_equal JSON.parse(actual, :symbolize_names => true), expected
593*1b3f573fSAndroid Build Coastguard Worker    end
594*1b3f573fSAndroid Build Coastguard Worker
595*1b3f573fSAndroid Build Coastguard Worker    def test_json_emit_defaults_submsg
596*1b3f573fSAndroid Build Coastguard Worker      m = TestSingularFields.new(singular_msg: proto_module::TestMessage2.new)
597*1b3f573fSAndroid Build Coastguard Worker
598*1b3f573fSAndroid Build Coastguard Worker      expected = {
599*1b3f573fSAndroid Build Coastguard Worker        singularInt32: 0,
600*1b3f573fSAndroid Build Coastguard Worker        singularInt64: "0",
601*1b3f573fSAndroid Build Coastguard Worker        singularUint32: 0,
602*1b3f573fSAndroid Build Coastguard Worker        singularUint64: "0",
603*1b3f573fSAndroid Build Coastguard Worker        singularBool: false,
604*1b3f573fSAndroid Build Coastguard Worker        singularFloat: 0,
605*1b3f573fSAndroid Build Coastguard Worker        singularDouble: 0,
606*1b3f573fSAndroid Build Coastguard Worker        singularString: "",
607*1b3f573fSAndroid Build Coastguard Worker        singularBytes: "",
608*1b3f573fSAndroid Build Coastguard Worker        singularMsg: {},
609*1b3f573fSAndroid Build Coastguard Worker        singularEnum: "Default",
610*1b3f573fSAndroid Build Coastguard Worker      }
611*1b3f573fSAndroid Build Coastguard Worker
612*1b3f573fSAndroid Build Coastguard Worker      actual = proto_module::TestMessage.encode_json(m, :emit_defaults => true)
613*1b3f573fSAndroid Build Coastguard Worker
614*1b3f573fSAndroid Build Coastguard Worker      assert_equal expected, JSON.parse(actual, :symbolize_names => true)
615*1b3f573fSAndroid Build Coastguard Worker    end
616*1b3f573fSAndroid Build Coastguard Worker
617*1b3f573fSAndroid Build Coastguard Worker    def test_respond_to
618*1b3f573fSAndroid Build Coastguard Worker      msg = MapMessage.new
619*1b3f573fSAndroid Build Coastguard Worker      assert msg.respond_to?(:map_string_int32)
620*1b3f573fSAndroid Build Coastguard Worker      assert !msg.respond_to?(:bacon)
621*1b3f573fSAndroid Build Coastguard Worker    end
622*1b3f573fSAndroid Build Coastguard Worker
623*1b3f573fSAndroid Build Coastguard Worker    def test_file_descriptor
624*1b3f573fSAndroid Build Coastguard Worker      file_descriptor = TestMessage.descriptor.file_descriptor
625*1b3f573fSAndroid Build Coastguard Worker      assert nil != file_descriptor
626*1b3f573fSAndroid Build Coastguard Worker      assert_equal "tests/basic_test.proto", file_descriptor.name
627*1b3f573fSAndroid Build Coastguard Worker      assert_equal :proto3, file_descriptor.syntax
628*1b3f573fSAndroid Build Coastguard Worker
629*1b3f573fSAndroid Build Coastguard Worker      file_descriptor = TestEnum.descriptor.file_descriptor
630*1b3f573fSAndroid Build Coastguard Worker      assert nil != file_descriptor
631*1b3f573fSAndroid Build Coastguard Worker      assert_equal "tests/basic_test.proto", file_descriptor.name
632*1b3f573fSAndroid Build Coastguard Worker      assert_equal :proto3, file_descriptor.syntax
633*1b3f573fSAndroid Build Coastguard Worker    end
634*1b3f573fSAndroid Build Coastguard Worker
635*1b3f573fSAndroid Build Coastguard Worker    # Ruby 2.5 changed to raise FrozenError instead of RuntimeError
636*1b3f573fSAndroid Build Coastguard Worker    FrozenErrorType = Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.5') ? RuntimeError : FrozenError
637*1b3f573fSAndroid Build Coastguard Worker
638*1b3f573fSAndroid Build Coastguard Worker    def test_map_freeze
639*1b3f573fSAndroid Build Coastguard Worker      m = proto_module::MapMessage.new
640*1b3f573fSAndroid Build Coastguard Worker      m.map_string_int32['a'] = 5
641*1b3f573fSAndroid Build Coastguard Worker      m.map_string_msg['b'] = proto_module::TestMessage2.new
642*1b3f573fSAndroid Build Coastguard Worker
643*1b3f573fSAndroid Build Coastguard Worker      m.map_string_int32.freeze
644*1b3f573fSAndroid Build Coastguard Worker      m.map_string_msg.freeze
645*1b3f573fSAndroid Build Coastguard Worker
646*1b3f573fSAndroid Build Coastguard Worker      assert m.map_string_int32.frozen?
647*1b3f573fSAndroid Build Coastguard Worker      assert m.map_string_msg.frozen?
648*1b3f573fSAndroid Build Coastguard Worker
649*1b3f573fSAndroid Build Coastguard Worker      assert_raise(FrozenErrorType) { m.map_string_int32['foo'] = 1 }
650*1b3f573fSAndroid Build Coastguard Worker      assert_raise(FrozenErrorType) { m.map_string_msg['bar'] = proto_module::TestMessage2.new }
651*1b3f573fSAndroid Build Coastguard Worker      assert_raise(FrozenErrorType) { m.map_string_int32.delete('a') }
652*1b3f573fSAndroid Build Coastguard Worker      assert_raise(FrozenErrorType) { m.map_string_int32.clear }
653*1b3f573fSAndroid Build Coastguard Worker    end
654*1b3f573fSAndroid Build Coastguard Worker
655*1b3f573fSAndroid Build Coastguard Worker    def test_map_length
656*1b3f573fSAndroid Build Coastguard Worker      m = proto_module::MapMessage.new
657*1b3f573fSAndroid Build Coastguard Worker      assert_equal 0, m.map_string_int32.length
658*1b3f573fSAndroid Build Coastguard Worker      assert_equal 0, m.map_string_msg.length
659*1b3f573fSAndroid Build Coastguard Worker      assert_equal 0, m.map_string_int32.size
660*1b3f573fSAndroid Build Coastguard Worker      assert_equal 0, m.map_string_msg.size
661*1b3f573fSAndroid Build Coastguard Worker
662*1b3f573fSAndroid Build Coastguard Worker      m.map_string_int32['a'] = 1
663*1b3f573fSAndroid Build Coastguard Worker      m.map_string_int32['b'] = 2
664*1b3f573fSAndroid Build Coastguard Worker      m.map_string_msg['a'] = proto_module::TestMessage2.new
665*1b3f573fSAndroid Build Coastguard Worker      assert_equal 2, m.map_string_int32.length
666*1b3f573fSAndroid Build Coastguard Worker      assert_equal 1, m.map_string_msg.length
667*1b3f573fSAndroid Build Coastguard Worker      assert_equal 2, m.map_string_int32.size
668*1b3f573fSAndroid Build Coastguard Worker      assert_equal 1, m.map_string_msg.size
669*1b3f573fSAndroid Build Coastguard Worker    end
670*1b3f573fSAndroid Build Coastguard Worker
671*1b3f573fSAndroid Build Coastguard Worker    def test_string_with_singleton_class_enabled
672*1b3f573fSAndroid Build Coastguard Worker      str = 'foobar'
673*1b3f573fSAndroid Build Coastguard Worker      # NOTE: Accessing a singleton class of an object changes its low level class representation
674*1b3f573fSAndroid Build Coastguard Worker      #       as far as the C API's CLASS_OF() method concerned, exposing the issue
675*1b3f573fSAndroid Build Coastguard Worker      str.singleton_class
676*1b3f573fSAndroid Build Coastguard Worker      m = proto_module::TestMessage.new(
677*1b3f573fSAndroid Build Coastguard Worker        optional_string: str,
678*1b3f573fSAndroid Build Coastguard Worker        optional_bytes: str
679*1b3f573fSAndroid Build Coastguard Worker      )
680*1b3f573fSAndroid Build Coastguard Worker
681*1b3f573fSAndroid Build Coastguard Worker      assert_equal str, m.optional_string
682*1b3f573fSAndroid Build Coastguard Worker      assert_equal str, m.optional_bytes
683*1b3f573fSAndroid Build Coastguard Worker    end
684*1b3f573fSAndroid Build Coastguard Worker
685*1b3f573fSAndroid Build Coastguard Worker    def test_utf8
686*1b3f573fSAndroid Build Coastguard Worker      m = proto_module::TestMessage.new(
687*1b3f573fSAndroid Build Coastguard Worker        optional_string: "µpb",
688*1b3f573fSAndroid Build Coastguard Worker      )
689*1b3f573fSAndroid Build Coastguard Worker      m2 = proto_module::TestMessage.decode(proto_module::TestMessage.encode(m))
690*1b3f573fSAndroid Build Coastguard Worker      assert_equal m2, m
691*1b3f573fSAndroid Build Coastguard Worker    end
692*1b3f573fSAndroid Build Coastguard Worker
693*1b3f573fSAndroid Build Coastguard Worker    def test_map_fields_respond_to? # regression test for issue 9202
694*1b3f573fSAndroid Build Coastguard Worker      msg = proto_module::MapMessage.new
695*1b3f573fSAndroid Build Coastguard Worker      assert msg.respond_to?(:map_string_int32=)
696*1b3f573fSAndroid Build Coastguard Worker      msg.map_string_int32 = Google::Protobuf::Map.new(:string, :int32)
697*1b3f573fSAndroid Build Coastguard Worker      assert msg.respond_to?(:map_string_int32)
698*1b3f573fSAndroid Build Coastguard Worker      assert_equal( Google::Protobuf::Map.new(:string, :int32), msg.map_string_int32 )
699*1b3f573fSAndroid Build Coastguard Worker      assert msg.respond_to?(:clear_map_string_int32)
700*1b3f573fSAndroid Build Coastguard Worker      msg.clear_map_string_int32
701*1b3f573fSAndroid Build Coastguard Worker
702*1b3f573fSAndroid Build Coastguard Worker      assert !msg.respond_to?(:has_map_string_int32?)
703*1b3f573fSAndroid Build Coastguard Worker      assert_raise NoMethodError do
704*1b3f573fSAndroid Build Coastguard Worker        msg.has_map_string_int32?
705*1b3f573fSAndroid Build Coastguard Worker      end
706*1b3f573fSAndroid Build Coastguard Worker      assert !msg.respond_to?(:map_string_int32_as_value)
707*1b3f573fSAndroid Build Coastguard Worker      assert_raise NoMethodError do
708*1b3f573fSAndroid Build Coastguard Worker        msg.map_string_int32_as_value
709*1b3f573fSAndroid Build Coastguard Worker      end
710*1b3f573fSAndroid Build Coastguard Worker      assert !msg.respond_to?(:map_string_int32_as_value=)
711*1b3f573fSAndroid Build Coastguard Worker      assert_raise NoMethodError do
712*1b3f573fSAndroid Build Coastguard Worker        msg.map_string_int32_as_value = :boom
713*1b3f573fSAndroid Build Coastguard Worker      end
714*1b3f573fSAndroid Build Coastguard Worker    end
715*1b3f573fSAndroid Build Coastguard Worker  end
716*1b3f573fSAndroid Build Coastguard Worker
717*1b3f573fSAndroid Build Coastguard Worker  def test_oneof_fields_respond_to? # regression test for issue 9202
718*1b3f573fSAndroid Build Coastguard Worker    msg = proto_module::OneofMessage.new
719*1b3f573fSAndroid Build Coastguard Worker    # `has_` prefix + "?" suffix actions should only work for oneofs fields.
720*1b3f573fSAndroid Build Coastguard Worker    assert msg.has_my_oneof?
721*1b3f573fSAndroid Build Coastguard Worker    assert msg.respond_to? :has_my_oneof?
722*1b3f573fSAndroid Build Coastguard Worker    assert !msg.respond_to?( :has_a? )
723*1b3f573fSAndroid Build Coastguard Worker    assert_raise NoMethodError do
724*1b3f573fSAndroid Build Coastguard Worker      msg.has_a?
725*1b3f573fSAndroid Build Coastguard Worker    end
726*1b3f573fSAndroid Build Coastguard Worker    assert !msg.respond_to?( :has_b? )
727*1b3f573fSAndroid Build Coastguard Worker    assert_raise NoMethodError do
728*1b3f573fSAndroid Build Coastguard Worker      msg.has_b?
729*1b3f573fSAndroid Build Coastguard Worker    end
730*1b3f573fSAndroid Build Coastguard Worker    assert !msg.respond_to?( :has_c? )
731*1b3f573fSAndroid Build Coastguard Worker    assert_raise NoMethodError do
732*1b3f573fSAndroid Build Coastguard Worker      msg.has_c?
733*1b3f573fSAndroid Build Coastguard Worker    end
734*1b3f573fSAndroid Build Coastguard Worker    assert !msg.respond_to?( :has_d? )
735*1b3f573fSAndroid Build Coastguard Worker    assert_raise NoMethodError do
736*1b3f573fSAndroid Build Coastguard Worker      msg.has_d?
737*1b3f573fSAndroid Build Coastguard Worker    end
738*1b3f573fSAndroid Build Coastguard Worker  end
739*1b3f573fSAndroid Build Coastguard Workerend
740