From c25d9feb4d791513c101061578e9e54fe180aa5f Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Wed, 26 Nov 2014 16:15:29 -0800 Subject: Down-integrate from internal code base. --- src/google/protobuf/dynamic_message_unittest.cc | 47 +++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'src/google/protobuf/dynamic_message_unittest.cc') diff --git a/src/google/protobuf/dynamic_message_unittest.cc b/src/google/protobuf/dynamic_message_unittest.cc index 6353ecbf..522a092a 100644 --- a/src/google/protobuf/dynamic_message_unittest.cc +++ b/src/google/protobuf/dynamic_message_unittest.cc @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -65,6 +66,8 @@ class DynamicMessageTest : public testing::Test { const Message* packed_prototype_; const Descriptor* oneof_descriptor_; const Message* oneof_prototype_; + const Descriptor* proto3_descriptor_; + const Message* proto3_prototype_; DynamicMessageTest(): factory_(&pool_) {} @@ -76,16 +79,20 @@ class DynamicMessageTest : public testing::Test { FileDescriptorProto unittest_file; FileDescriptorProto unittest_import_file; FileDescriptorProto unittest_import_public_file; + FileDescriptorProto unittest_no_field_presence_file; unittest::TestAllTypes::descriptor()->file()->CopyTo(&unittest_file); unittest_import::ImportMessage::descriptor()->file()->CopyTo( &unittest_import_file); unittest_import::PublicImportMessage::descriptor()->file()->CopyTo( &unittest_import_public_file); + proto2_nofieldpresence_unittest::TestAllTypes::descriptor()-> + file()->CopyTo(&unittest_no_field_presence_file); ASSERT_TRUE(pool_.BuildFile(unittest_import_public_file) != NULL); ASSERT_TRUE(pool_.BuildFile(unittest_import_file) != NULL); ASSERT_TRUE(pool_.BuildFile(unittest_file) != NULL); + ASSERT_TRUE(pool_.BuildFile(unittest_no_field_presence_file) != NULL); descriptor_ = pool_.FindMessageTypeByName("protobuf_unittest.TestAllTypes"); ASSERT_TRUE(descriptor_ != NULL); @@ -105,6 +112,12 @@ class DynamicMessageTest : public testing::Test { pool_.FindMessageTypeByName("protobuf_unittest.TestOneof2"); ASSERT_TRUE(oneof_descriptor_ != NULL); oneof_prototype_ = factory_.GetPrototype(oneof_descriptor_); + + proto3_descriptor_ = + pool_.FindMessageTypeByName( + "proto2_nofieldpresence_unittest.TestAllTypes"); + ASSERT_TRUE(proto3_descriptor_ != NULL); + proto3_prototype_ = factory_.GetPrototype(proto3_descriptor_); } }; @@ -233,6 +246,40 @@ TEST_F(DynamicMessageTest, Arena) { // Return without freeing: should not leak. } +TEST_F(DynamicMessageTest, Proto3) { + Message* message = proto3_prototype_->New(); + const Reflection* refl = message->GetReflection(); + const Descriptor* desc = message->GetDescriptor(); + + // Just test a single primtive and single message field here to make sure we + // are getting the no-field-presence semantics elsewhere. DynamicMessage uses + // GeneratedMessageReflection under the hood, so the rest should be fine as + // long as GMR recognizes that we're using a proto3 message. + const FieldDescriptor* optional_int32 = + desc->FindFieldByName("optional_int32"); + const FieldDescriptor* optional_msg = + desc->FindFieldByName("optional_nested_message"); + EXPECT_TRUE(optional_int32 != NULL); + EXPECT_TRUE(optional_msg != NULL); + + EXPECT_EQ(false, refl->HasField(*message, optional_int32)); + refl->SetInt32(message, optional_int32, 42); + EXPECT_EQ(true, refl->HasField(*message, optional_int32)); + refl->SetInt32(message, optional_int32, 0); + EXPECT_EQ(false, refl->HasField(*message, optional_int32)); + + EXPECT_EQ(false, refl->HasField(*message, optional_msg)); + refl->MutableMessage(message, optional_msg); + EXPECT_EQ(true, refl->HasField(*message, optional_msg)); + delete refl->ReleaseMessage(message, optional_msg); + EXPECT_EQ(false, refl->HasField(*message, optional_msg)); + + // Also ensure that the default instance handles field presence properly. + EXPECT_EQ(false, refl->HasField(*proto3_prototype_, optional_msg)); + + delete message; +} + } // namespace protobuf } // namespace google -- cgit v1.2.3