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