| // Protocol Buffers - Google's data interchange format |
| // Copyright 2008 Google Inc. All rights reserved. |
| // https://developers.google.com/protocol-buffers/ |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are |
| // met: |
| // |
| // * Redistributions of source code must retain the above copyright |
| // notice, this list of conditions and the following disclaimer. |
| // * Redistributions in binary form must reproduce the above |
| // copyright notice, this list of conditions and the following disclaimer |
| // in the documentation and/or other materials provided with the |
| // distribution. |
| // * Neither the name of Google Inc. nor the names of its |
| // contributors may be used to endorse or promote products derived from |
| // this software without specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| // Author: kenton@google.com (Kenton Varda) |
| // Based on original Protocol Buffers design by |
| // Sanjay Ghemawat, Jeff Dean, and others. |
| // |
| // To test GeneratedMessageReflection, we actually let the protocol compiler |
| // generate a full protocol message implementation and then test its |
| // reflection interface. This is much easier and more maintainable than |
| // trying to create our own Message class for GeneratedMessageReflection |
| // to wrap. |
| // |
| // The tests here closely mirror some of the tests in |
| // compiler/cpp/unittest, except using the reflection interface |
| // rather than generated accessors. |
| |
| #include <google/protobuf/generated_message_reflection.h> |
| #include <memory> |
| #ifndef _SHARED_PTR_H |
| #include <google/protobuf/stubs/shared_ptr.h> |
| #endif |
| |
| #include <google/protobuf/descriptor.h> |
| #include <google/protobuf/test_util.h> |
| #include <google/protobuf/unittest.pb.h> |
| |
| #include <google/protobuf/stubs/logging.h> |
| #include <google/protobuf/stubs/common.h> |
| #include <google/protobuf/testing/googletest.h> |
| #include <gtest/gtest.h> |
| |
| namespace google { |
| namespace protobuf { |
| |
| namespace { |
| |
| // Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes. |
| const FieldDescriptor* F(const string& name) { |
| const FieldDescriptor* result = |
| unittest::TestAllTypes::descriptor()->FindFieldByName(name); |
| GOOGLE_CHECK(result != NULL); |
| return result; |
| } |
| |
| TEST(GeneratedMessageReflectionTest, Defaults) { |
| // Check that all default values are set correctly in the initial message. |
| unittest::TestAllTypes message; |
| TestUtil::ReflectionTester reflection_tester( |
| unittest::TestAllTypes::descriptor()); |
| |
| reflection_tester.ExpectClearViaReflection(message); |
| |
| const Reflection* reflection = message.GetReflection(); |
| |
| // Messages should return pointers to default instances until first use. |
| // (This is not checked by ExpectClear() since it is not actually true after |
| // the fields have been set and then cleared.) |
| EXPECT_EQ(&unittest::TestAllTypes::OptionalGroup::default_instance(), |
| &reflection->GetMessage(message, F("optionalgroup"))); |
| EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(), |
| &reflection->GetMessage(message, F("optional_nested_message"))); |
| EXPECT_EQ(&unittest::ForeignMessage::default_instance(), |
| &reflection->GetMessage(message, F("optional_foreign_message"))); |
| EXPECT_EQ(&unittest_import::ImportMessage::default_instance(), |
| &reflection->GetMessage(message, F("optional_import_message"))); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, Accessors) { |
| // Set every field to a unique value then go back and check all those |
| // values. |
| unittest::TestAllTypes message; |
| TestUtil::ReflectionTester reflection_tester( |
| unittest::TestAllTypes::descriptor()); |
| |
| reflection_tester.SetAllFieldsViaReflection(&message); |
| TestUtil::ExpectAllFieldsSet(message); |
| reflection_tester.ExpectAllFieldsSetViaReflection(message); |
| |
| reflection_tester.ModifyRepeatedFieldsViaReflection(&message); |
| TestUtil::ExpectRepeatedFieldsModified(message); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, GetStringReference) { |
| // Test that GetStringReference() returns the underlying string when it is |
| // a normal string field. |
| unittest::TestAllTypes message; |
| message.set_optional_string("foo"); |
| message.add_repeated_string("foo"); |
| |
| const Reflection* reflection = message.GetReflection(); |
| string scratch; |
| |
| EXPECT_EQ(&message.optional_string(), |
| &reflection->GetStringReference(message, F("optional_string"), &scratch)) |
| << "For simple string fields, GetStringReference() should return a " |
| "reference to the underlying string."; |
| EXPECT_EQ(&message.repeated_string(0), |
| &reflection->GetRepeatedStringReference(message, F("repeated_string"), |
| 0, &scratch)) |
| << "For simple string fields, GetRepeatedStringReference() should return " |
| "a reference to the underlying string."; |
| } |
| |
| |
| TEST(GeneratedMessageReflectionTest, DefaultsAfterClear) { |
| // Check that after setting all fields and then clearing, getting an |
| // embedded message does NOT return the default instance. |
| unittest::TestAllTypes message; |
| TestUtil::ReflectionTester reflection_tester( |
| unittest::TestAllTypes::descriptor()); |
| |
| TestUtil::SetAllFields(&message); |
| message.Clear(); |
| |
| const Reflection* reflection = message.GetReflection(); |
| |
| EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(), |
| &reflection->GetMessage(message, F("optionalgroup"))); |
| EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(), |
| &reflection->GetMessage(message, F("optional_nested_message"))); |
| EXPECT_NE(&unittest::ForeignMessage::default_instance(), |
| &reflection->GetMessage(message, F("optional_foreign_message"))); |
| EXPECT_NE(&unittest_import::ImportMessage::default_instance(), |
| &reflection->GetMessage(message, F("optional_import_message"))); |
| } |
| |
| |
| TEST(GeneratedMessageReflectionTest, Swap) { |
| unittest::TestAllTypes message1; |
| unittest::TestAllTypes message2; |
| |
| TestUtil::SetAllFields(&message1); |
| |
| const Reflection* reflection = message1.GetReflection(); |
| reflection->Swap(&message1, &message2); |
| |
| TestUtil::ExpectClear(message1); |
| TestUtil::ExpectAllFieldsSet(message2); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, SwapWithBothSet) { |
| unittest::TestAllTypes message1; |
| unittest::TestAllTypes message2; |
| |
| TestUtil::SetAllFields(&message1); |
| TestUtil::SetAllFields(&message2); |
| TestUtil::ModifyRepeatedFields(&message2); |
| |
| const Reflection* reflection = message1.GetReflection(); |
| reflection->Swap(&message1, &message2); |
| |
| TestUtil::ExpectRepeatedFieldsModified(message1); |
| TestUtil::ExpectAllFieldsSet(message2); |
| |
| message1.set_optional_int32(532819); |
| |
| reflection->Swap(&message1, &message2); |
| |
| EXPECT_EQ(532819, message2.optional_int32()); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, SwapExtensions) { |
| unittest::TestAllExtensions message1; |
| unittest::TestAllExtensions message2; |
| |
| TestUtil::SetAllExtensions(&message1); |
| |
| const Reflection* reflection = message1.GetReflection(); |
| reflection->Swap(&message1, &message2); |
| |
| TestUtil::ExpectExtensionsClear(message1); |
| TestUtil::ExpectAllExtensionsSet(message2); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, SwapUnknown) { |
| unittest::TestEmptyMessage message1, message2; |
| |
| message1.mutable_unknown_fields()->AddVarint(1234, 1); |
| |
| EXPECT_EQ(1, message1.unknown_fields().field_count()); |
| EXPECT_EQ(0, message2.unknown_fields().field_count()); |
| const Reflection* reflection = message1.GetReflection(); |
| reflection->Swap(&message1, &message2); |
| EXPECT_EQ(0, message1.unknown_fields().field_count()); |
| EXPECT_EQ(1, message2.unknown_fields().field_count()); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, SwapFields) { |
| unittest::TestAllTypes message1, message2; |
| message1.set_optional_double(12.3); |
| message1.mutable_repeated_int32()->Add(10); |
| message1.mutable_repeated_int32()->Add(20); |
| |
| message2.set_optional_string("hello"); |
| message2.mutable_repeated_int64()->Add(30); |
| |
| vector<const FieldDescriptor*> fields; |
| const Descriptor* descriptor = message1.GetDescriptor(); |
| fields.push_back(descriptor->FindFieldByName("optional_double")); |
| fields.push_back(descriptor->FindFieldByName("repeated_int32")); |
| fields.push_back(descriptor->FindFieldByName("optional_string")); |
| fields.push_back(descriptor->FindFieldByName("optional_uint64")); |
| |
| const Reflection* reflection = message1.GetReflection(); |
| reflection->SwapFields(&message1, &message2, fields); |
| |
| EXPECT_FALSE(message1.has_optional_double()); |
| EXPECT_EQ(0, message1.repeated_int32_size()); |
| EXPECT_TRUE(message1.has_optional_string()); |
| EXPECT_EQ("hello", message1.optional_string()); |
| EXPECT_EQ(0, message1.repeated_int64_size()); |
| EXPECT_FALSE(message1.has_optional_uint64()); |
| |
| EXPECT_TRUE(message2.has_optional_double()); |
| EXPECT_EQ(12.3, message2.optional_double()); |
| EXPECT_EQ(2, message2.repeated_int32_size()); |
| EXPECT_EQ(10, message2.repeated_int32(0)); |
| EXPECT_EQ(20, message2.repeated_int32(1)); |
| EXPECT_FALSE(message2.has_optional_string()); |
| EXPECT_EQ(1, message2.repeated_int64_size()); |
| EXPECT_FALSE(message2.has_optional_uint64()); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, SwapFieldsAll) { |
| unittest::TestAllTypes message1; |
| unittest::TestAllTypes message2; |
| |
| TestUtil::SetAllFields(&message2); |
| |
| vector<const FieldDescriptor*> fields; |
| const Reflection* reflection = message1.GetReflection(); |
| reflection->ListFields(message2, &fields); |
| reflection->SwapFields(&message1, &message2, fields); |
| |
| TestUtil::ExpectAllFieldsSet(message1); |
| TestUtil::ExpectClear(message2); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, SwapFieldsAllExtension) { |
| unittest::TestAllExtensions message1; |
| unittest::TestAllExtensions message2; |
| |
| TestUtil::SetAllExtensions(&message1); |
| |
| vector<const FieldDescriptor*> fields; |
| const Reflection* reflection = message1.GetReflection(); |
| reflection->ListFields(message1, &fields); |
| reflection->SwapFields(&message1, &message2, fields); |
| |
| TestUtil::ExpectExtensionsClear(message1); |
| TestUtil::ExpectAllExtensionsSet(message2); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, SwapOneof) { |
| unittest::TestOneof2 message1, message2; |
| TestUtil::SetOneof1(&message1); |
| |
| const Reflection* reflection = message1.GetReflection(); |
| reflection->Swap(&message1, &message2); |
| |
| TestUtil::ExpectOneofClear(message1); |
| TestUtil::ExpectOneofSet1(message2); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, SwapOneofBothSet) { |
| unittest::TestOneof2 message1, message2; |
| TestUtil::SetOneof1(&message1); |
| TestUtil::SetOneof2(&message2); |
| |
| const Reflection* reflection = message1.GetReflection(); |
| reflection->Swap(&message1, &message2); |
| |
| TestUtil::ExpectOneofSet2(message1); |
| TestUtil::ExpectOneofSet1(message2); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, SwapFieldsOneof) { |
| unittest::TestOneof2 message1, message2; |
| TestUtil::SetOneof1(&message1); |
| |
| vector<const FieldDescriptor*> fields; |
| const Descriptor* descriptor = message1.GetDescriptor(); |
| for (int i = 0; i < descriptor->field_count(); i++) { |
| fields.push_back(descriptor->field(i)); |
| } |
| const Reflection* reflection = message1.GetReflection(); |
| reflection->SwapFields(&message1, &message2, fields); |
| |
| TestUtil::ExpectOneofClear(message1); |
| TestUtil::ExpectOneofSet1(message2); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, RemoveLast) { |
| unittest::TestAllTypes message; |
| TestUtil::ReflectionTester reflection_tester( |
| unittest::TestAllTypes::descriptor()); |
| |
| TestUtil::SetAllFields(&message); |
| |
| reflection_tester.RemoveLastRepeatedsViaReflection(&message); |
| |
| TestUtil::ExpectLastRepeatedsRemoved(message); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, RemoveLastExtensions) { |
| unittest::TestAllExtensions message; |
| TestUtil::ReflectionTester reflection_tester( |
| unittest::TestAllExtensions::descriptor()); |
| |
| TestUtil::SetAllExtensions(&message); |
| |
| reflection_tester.RemoveLastRepeatedsViaReflection(&message); |
| |
| TestUtil::ExpectLastRepeatedExtensionsRemoved(message); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, ReleaseLast) { |
| unittest::TestAllTypes message; |
| const Descriptor* descriptor = message.GetDescriptor(); |
| TestUtil::ReflectionTester reflection_tester(descriptor); |
| |
| TestUtil::SetAllFields(&message); |
| |
| reflection_tester.ReleaseLastRepeatedsViaReflection(&message, false); |
| |
| TestUtil::ExpectLastRepeatedsReleased(message); |
| |
| // Now test that we actually release the right message. |
| message.Clear(); |
| TestUtil::SetAllFields(&message); |
| ASSERT_EQ(2, message.repeated_foreign_message_size()); |
| const protobuf_unittest::ForeignMessage* expected = |
| message.mutable_repeated_foreign_message(1); |
| google::protobuf::scoped_ptr<Message> released(message.GetReflection()->ReleaseLast( |
| &message, descriptor->FindFieldByName("repeated_foreign_message"))); |
| EXPECT_EQ(expected, released.get()); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, ReleaseLastExtensions) { |
| unittest::TestAllExtensions message; |
| const Descriptor* descriptor = message.GetDescriptor(); |
| TestUtil::ReflectionTester reflection_tester(descriptor); |
| |
| TestUtil::SetAllExtensions(&message); |
| |
| reflection_tester.ReleaseLastRepeatedsViaReflection(&message, true); |
| |
| TestUtil::ExpectLastRepeatedExtensionsReleased(message); |
| |
| // Now test that we actually release the right message. |
| message.Clear(); |
| TestUtil::SetAllExtensions(&message); |
| ASSERT_EQ(2, message.ExtensionSize( |
| unittest::repeated_foreign_message_extension)); |
| const protobuf_unittest::ForeignMessage* expected = message.MutableExtension( |
| unittest::repeated_foreign_message_extension, 1); |
| google::protobuf::scoped_ptr<Message> released(message.GetReflection()->ReleaseLast( |
| &message, descriptor->file()->FindExtensionByName( |
| "repeated_foreign_message_extension"))); |
| EXPECT_EQ(expected, released.get()); |
| |
| } |
| |
| TEST(GeneratedMessageReflectionTest, SwapRepeatedElements) { |
| unittest::TestAllTypes message; |
| TestUtil::ReflectionTester reflection_tester( |
| unittest::TestAllTypes::descriptor()); |
| |
| TestUtil::SetAllFields(&message); |
| |
| // Swap and test that fields are all swapped. |
| reflection_tester.SwapRepeatedsViaReflection(&message); |
| TestUtil::ExpectRepeatedsSwapped(message); |
| |
| // Swap back and test that fields are all back to original values. |
| reflection_tester.SwapRepeatedsViaReflection(&message); |
| TestUtil::ExpectAllFieldsSet(message); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, SwapRepeatedElementsExtension) { |
| unittest::TestAllExtensions message; |
| TestUtil::ReflectionTester reflection_tester( |
| unittest::TestAllExtensions::descriptor()); |
| |
| TestUtil::SetAllExtensions(&message); |
| |
| // Swap and test that fields are all swapped. |
| reflection_tester.SwapRepeatedsViaReflection(&message); |
| TestUtil::ExpectRepeatedExtensionsSwapped(message); |
| |
| // Swap back and test that fields are all back to original values. |
| reflection_tester.SwapRepeatedsViaReflection(&message); |
| TestUtil::ExpectAllExtensionsSet(message); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, Extensions) { |
| // Set every extension to a unique value then go back and check all those |
| // values. |
| unittest::TestAllExtensions message; |
| TestUtil::ReflectionTester reflection_tester( |
| unittest::TestAllExtensions::descriptor()); |
| |
| reflection_tester.SetAllFieldsViaReflection(&message); |
| TestUtil::ExpectAllExtensionsSet(message); |
| reflection_tester.ExpectAllFieldsSetViaReflection(message); |
| |
| reflection_tester.ModifyRepeatedFieldsViaReflection(&message); |
| TestUtil::ExpectRepeatedExtensionsModified(message); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, FindExtensionTypeByNumber) { |
| const Reflection* reflection = |
| unittest::TestAllExtensions::default_instance().GetReflection(); |
| |
| const FieldDescriptor* extension1 = |
| unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( |
| "optional_int32_extension"); |
| const FieldDescriptor* extension2 = |
| unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( |
| "repeated_string_extension"); |
| |
| EXPECT_EQ(extension1, |
| reflection->FindKnownExtensionByNumber(extension1->number())); |
| EXPECT_EQ(extension2, |
| reflection->FindKnownExtensionByNumber(extension2->number())); |
| |
| // Non-existent extension. |
| EXPECT_TRUE(reflection->FindKnownExtensionByNumber(62341) == NULL); |
| |
| // Extensions of TestAllExtensions should not show up as extensions of |
| // other types. |
| EXPECT_TRUE(unittest::TestAllTypes::default_instance().GetReflection()-> |
| FindKnownExtensionByNumber(extension1->number()) == NULL); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, FindKnownExtensionByName) { |
| const Reflection* reflection = |
| unittest::TestAllExtensions::default_instance().GetReflection(); |
| |
| const FieldDescriptor* extension1 = |
| unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( |
| "optional_int32_extension"); |
| const FieldDescriptor* extension2 = |
| unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( |
| "repeated_string_extension"); |
| |
| EXPECT_EQ(extension1, |
| reflection->FindKnownExtensionByName(extension1->full_name())); |
| EXPECT_EQ(extension2, |
| reflection->FindKnownExtensionByName(extension2->full_name())); |
| |
| // Non-existent extension. |
| EXPECT_TRUE(reflection->FindKnownExtensionByName("no_such_ext") == NULL); |
| |
| // Extensions of TestAllExtensions should not show up as extensions of |
| // other types. |
| EXPECT_TRUE(unittest::TestAllTypes::default_instance().GetReflection()-> |
| FindKnownExtensionByName(extension1->full_name()) == NULL); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, SetAllocatedMessageTest) { |
| unittest::TestAllTypes from_message1; |
| unittest::TestAllTypes from_message2; |
| unittest::TestAllTypes to_message; |
| TestUtil::ReflectionTester reflection_tester( |
| unittest::TestAllTypes::descriptor()); |
| reflection_tester.SetAllFieldsViaReflection(&from_message1); |
| reflection_tester.SetAllFieldsViaReflection(&from_message2); |
| |
| // Before moving fields, we expect the nested messages to be NULL. |
| reflection_tester.ExpectMessagesReleasedViaReflection( |
| &to_message, TestUtil::ReflectionTester::IS_NULL); |
| |
| // After fields are moved we should get non-NULL releases. |
| reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection( |
| &from_message1, &to_message); |
| reflection_tester.ExpectMessagesReleasedViaReflection( |
| &to_message, TestUtil::ReflectionTester::NOT_NULL); |
| |
| // Another move to make sure that we can SetAllocated several times. |
| reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection( |
| &from_message2, &to_message); |
| reflection_tester.ExpectMessagesReleasedViaReflection( |
| &to_message, TestUtil::ReflectionTester::NOT_NULL); |
| |
| // After SetAllocatedOptionalMessageFieldsToNullViaReflection() we expect the |
| // releases to be NULL again. |
| reflection_tester.SetAllocatedOptionalMessageFieldsToNullViaReflection( |
| &to_message); |
| reflection_tester.ExpectMessagesReleasedViaReflection( |
| &to_message, TestUtil::ReflectionTester::IS_NULL); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, SetAllocatedExtensionMessageTest) { |
| unittest::TestAllExtensions from_message1; |
| unittest::TestAllExtensions from_message2; |
| unittest::TestAllExtensions to_message; |
| TestUtil::ReflectionTester reflection_tester( |
| unittest::TestAllExtensions::descriptor()); |
| reflection_tester.SetAllFieldsViaReflection(&from_message1); |
| reflection_tester.SetAllFieldsViaReflection(&from_message2); |
| |
| // Before moving fields, we expect the nested messages to be NULL. |
| reflection_tester.ExpectMessagesReleasedViaReflection( |
| &to_message, TestUtil::ReflectionTester::IS_NULL); |
| |
| // After fields are moved we should get non-NULL releases. |
| reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection( |
| &from_message1, &to_message); |
| reflection_tester.ExpectMessagesReleasedViaReflection( |
| &to_message, TestUtil::ReflectionTester::NOT_NULL); |
| |
| // Another move to make sure that we can SetAllocated several times. |
| reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection( |
| &from_message2, &to_message); |
| reflection_tester.ExpectMessagesReleasedViaReflection( |
| &to_message, TestUtil::ReflectionTester::NOT_NULL); |
| |
| // After SetAllocatedOptionalMessageFieldsToNullViaReflection() we expect the |
| // releases to be NULL again. |
| reflection_tester.SetAllocatedOptionalMessageFieldsToNullViaReflection( |
| &to_message); |
| reflection_tester.ExpectMessagesReleasedViaReflection( |
| &to_message, TestUtil::ReflectionTester::IS_NULL); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, AddRepeatedMessage) { |
| unittest::TestAllTypes message; |
| |
| const Reflection* reflection = message.GetReflection(); |
| const Reflection* nested_reflection = |
| unittest::TestAllTypes::NestedMessage::default_instance().GetReflection(); |
| |
| const FieldDescriptor* nested_bb = |
| unittest::TestAllTypes::NestedMessage::descriptor()->FindFieldByName( |
| "bb"); |
| |
| Message* nested = reflection->AddMessage( |
| &message, F("repeated_nested_message")); |
| nested_reflection->SetInt32(nested, nested_bb, 11); |
| |
| EXPECT_EQ(11, message.repeated_nested_message(0).bb()); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, MutableRepeatedMessage) { |
| unittest::TestAllTypes message; |
| |
| const Reflection* reflection = message.GetReflection(); |
| const Reflection* nested_reflection = |
| unittest::TestAllTypes::NestedMessage::default_instance().GetReflection(); |
| |
| const FieldDescriptor* nested_bb = |
| unittest::TestAllTypes::NestedMessage::descriptor()->FindFieldByName( |
| "bb"); |
| |
| message.add_repeated_nested_message()->set_bb(12); |
| |
| Message* nested = reflection->MutableRepeatedMessage( |
| &message, F("repeated_nested_message"), 0); |
| EXPECT_EQ(12, nested_reflection->GetInt32(*nested, nested_bb)); |
| nested_reflection->SetInt32(nested, nested_bb, 13); |
| EXPECT_EQ(13, message.repeated_nested_message(0).bb()); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, AddAllocatedMessage) { |
| unittest::TestAllTypes message; |
| |
| const Reflection* reflection = message.GetReflection(); |
| |
| unittest::TestAllTypes::NestedMessage* nested = |
| new unittest::TestAllTypes::NestedMessage(); |
| nested->set_bb(11); |
| reflection->AddAllocatedMessage(&message, F("repeated_nested_message"), nested); |
| EXPECT_EQ(1, message.repeated_nested_message_size()); |
| EXPECT_EQ(11, message.repeated_nested_message(0).bb()); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, ListFieldsOneOf) { |
| unittest::TestOneof2 message; |
| TestUtil::SetOneof1(&message); |
| |
| const Reflection* reflection = message.GetReflection(); |
| vector<const FieldDescriptor*> fields; |
| reflection->ListFields(message, &fields); |
| EXPECT_EQ(4, fields.size()); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, Oneof) { |
| unittest::TestOneof2 message; |
| const Descriptor* descriptor = message.GetDescriptor(); |
| const Reflection* reflection = message.GetReflection(); |
| |
| // Check default values. |
| EXPECT_EQ(0, reflection->GetInt32( |
| message, descriptor->FindFieldByName("foo_int"))); |
| EXPECT_EQ("", reflection->GetString( |
| message, descriptor->FindFieldByName("foo_string"))); |
| EXPECT_EQ("", reflection->GetString( |
| message, descriptor->FindFieldByName("foo_cord"))); |
| EXPECT_EQ("", reflection->GetString( |
| message, descriptor->FindFieldByName("foo_string_piece"))); |
| EXPECT_EQ("", reflection->GetString( |
| message, descriptor->FindFieldByName("foo_bytes"))); |
| EXPECT_EQ(unittest::TestOneof2::FOO, reflection->GetEnum( |
| message, descriptor->FindFieldByName("foo_enum"))->number()); |
| EXPECT_EQ(&unittest::TestOneof2::NestedMessage::default_instance(), |
| &reflection->GetMessage( |
| message, descriptor->FindFieldByName("foo_message"))); |
| EXPECT_EQ(&unittest::TestOneof2::FooGroup::default_instance(), |
| &reflection->GetMessage( |
| message, descriptor->FindFieldByName("foogroup"))); |
| EXPECT_NE(&unittest::TestOneof2::FooGroup::default_instance(), |
| &reflection->GetMessage( |
| message, descriptor->FindFieldByName("foo_lazy_message"))); |
| EXPECT_EQ(5, reflection->GetInt32( |
| message, descriptor->FindFieldByName("bar_int"))); |
| EXPECT_EQ("STRING", reflection->GetString( |
| message, descriptor->FindFieldByName("bar_string"))); |
| EXPECT_EQ("CORD", reflection->GetString( |
| message, descriptor->FindFieldByName("bar_cord"))); |
| EXPECT_EQ("SPIECE", reflection->GetString( |
| message, descriptor->FindFieldByName("bar_string_piece"))); |
| EXPECT_EQ("BYTES", reflection->GetString( |
| message, descriptor->FindFieldByName("bar_bytes"))); |
| EXPECT_EQ(unittest::TestOneof2::BAR, reflection->GetEnum( |
| message, descriptor->FindFieldByName("bar_enum"))->number()); |
| |
| // Check Set functions. |
| reflection->SetInt32( |
| &message, descriptor->FindFieldByName("foo_int"), 123); |
| EXPECT_EQ(123, reflection->GetInt32( |
| message, descriptor->FindFieldByName("foo_int"))); |
| reflection->SetString( |
| &message, descriptor->FindFieldByName("foo_string"), "abc"); |
| EXPECT_EQ("abc", reflection->GetString( |
| message, descriptor->FindFieldByName("foo_string"))); |
| reflection->SetString( |
| &message, descriptor->FindFieldByName("foo_bytes"), "bytes"); |
| EXPECT_EQ("bytes", reflection->GetString( |
| message, descriptor->FindFieldByName("foo_bytes"))); |
| reflection->SetString( |
| &message, descriptor->FindFieldByName("bar_cord"), "change_cord"); |
| EXPECT_EQ("change_cord", reflection->GetString( |
| message, descriptor->FindFieldByName("bar_cord"))); |
| reflection->SetString( |
| &message, descriptor->FindFieldByName("bar_string_piece"), |
| "change_spiece"); |
| EXPECT_EQ("change_spiece", reflection->GetString( |
| message, descriptor->FindFieldByName("bar_string_piece"))); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, SetAllocatedOneofMessageTest) { |
| unittest::TestOneof2 from_message1; |
| unittest::TestOneof2 from_message2; |
| unittest::TestOneof2 to_message; |
| const Descriptor* descriptor = unittest::TestOneof2::descriptor(); |
| const Reflection* reflection = to_message.GetReflection(); |
| |
| Message* released = reflection->ReleaseMessage( |
| &to_message, descriptor->FindFieldByName("foo_lazy_message")); |
| EXPECT_TRUE(released == NULL); |
| released = reflection->ReleaseMessage( |
| &to_message, descriptor->FindFieldByName("foo_message")); |
| EXPECT_TRUE(released == NULL); |
| |
| TestUtil::ReflectionTester::SetOneofViaReflection(&from_message1); |
| TestUtil::ReflectionTester::ExpectOneofSetViaReflection(from_message1); |
| |
| TestUtil::ReflectionTester:: |
| SetAllocatedOptionalMessageFieldsToMessageViaReflection( |
| &from_message1, &to_message); |
| const Message& sub_message = reflection->GetMessage( |
| to_message, descriptor->FindFieldByName("foo_lazy_message")); |
| released = reflection->ReleaseMessage( |
| &to_message, descriptor->FindFieldByName("foo_lazy_message")); |
| EXPECT_TRUE(released != NULL); |
| EXPECT_EQ(&sub_message, released); |
| delete released; |
| |
| TestUtil::ReflectionTester::SetOneofViaReflection(&from_message2); |
| |
| reflection->MutableMessage( |
| &from_message2, descriptor->FindFieldByName("foo_message")); |
| |
| TestUtil::ReflectionTester:: |
| SetAllocatedOptionalMessageFieldsToMessageViaReflection( |
| &from_message2, &to_message); |
| |
| const Message& sub_message2 = reflection->GetMessage( |
| to_message, descriptor->FindFieldByName("foo_message")); |
| released = reflection->ReleaseMessage( |
| &to_message, descriptor->FindFieldByName("foo_message")); |
| EXPECT_TRUE(released != NULL); |
| EXPECT_EQ(&sub_message2, released); |
| delete released; |
| } |
| |
| TEST(GeneratedMessageReflectionTest, ReleaseMessageTest) { |
| unittest::TestAllTypes message; |
| TestUtil::ReflectionTester reflection_tester( |
| unittest::TestAllTypes::descriptor()); |
| |
| // When nothing is set, we expect all released messages to be NULL. |
| reflection_tester.ExpectMessagesReleasedViaReflection( |
| &message, TestUtil::ReflectionTester::IS_NULL); |
| |
| // After fields are set we should get non-NULL releases. |
| reflection_tester.SetAllFieldsViaReflection(&message); |
| reflection_tester.ExpectMessagesReleasedViaReflection( |
| &message, TestUtil::ReflectionTester::NOT_NULL); |
| |
| // After Clear() we may or may not get a message from ReleaseMessage(). |
| // This is implementation specific. |
| reflection_tester.SetAllFieldsViaReflection(&message); |
| message.Clear(); |
| reflection_tester.ExpectMessagesReleasedViaReflection( |
| &message, TestUtil::ReflectionTester::CAN_BE_NULL); |
| |
| // Test a different code path for setting after releasing. |
| TestUtil::SetAllFields(&message); |
| TestUtil::ExpectAllFieldsSet(message); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, ReleaseExtensionMessageTest) { |
| unittest::TestAllExtensions message; |
| TestUtil::ReflectionTester reflection_tester( |
| unittest::TestAllExtensions::descriptor()); |
| |
| // When nothing is set, we expect all released messages to be NULL. |
| reflection_tester.ExpectMessagesReleasedViaReflection( |
| &message, TestUtil::ReflectionTester::IS_NULL); |
| |
| // After fields are set we should get non-NULL releases. |
| reflection_tester.SetAllFieldsViaReflection(&message); |
| reflection_tester.ExpectMessagesReleasedViaReflection( |
| &message, TestUtil::ReflectionTester::NOT_NULL); |
| |
| // After Clear() we may or may not get a message from ReleaseMessage(). |
| // This is implementation specific. |
| reflection_tester.SetAllFieldsViaReflection(&message); |
| message.Clear(); |
| reflection_tester.ExpectMessagesReleasedViaReflection( |
| &message, TestUtil::ReflectionTester::CAN_BE_NULL); |
| |
| // Test a different code path for setting after releasing. |
| TestUtil::SetAllExtensions(&message); |
| TestUtil::ExpectAllExtensionsSet(message); |
| } |
| |
| TEST(GeneratedMessageReflectionTest, ReleaseOneofMessageTest) { |
| unittest::TestOneof2 message; |
| TestUtil::ReflectionTester::SetOneofViaReflection(&message); |
| |
| const Descriptor* descriptor = unittest::TestOneof2::descriptor(); |
| const Reflection* reflection = message.GetReflection(); |
| const Message& sub_message = reflection->GetMessage( |
| message, descriptor->FindFieldByName("foo_lazy_message")); |
| Message* released = reflection->ReleaseMessage( |
| &message, descriptor->FindFieldByName("foo_lazy_message")); |
| |
| EXPECT_TRUE(released != NULL); |
| EXPECT_EQ(&sub_message, released); |
| delete released; |
| |
| released = reflection->ReleaseMessage( |
| &message, descriptor->FindFieldByName("foo_lazy_message")); |
| EXPECT_TRUE(released == NULL); |
| } |
| |
| #ifdef PROTOBUF_HAS_DEATH_TEST |
| |
| TEST(GeneratedMessageReflectionTest, UsageErrors) { |
| unittest::TestAllTypes message; |
| const Reflection* reflection = message.GetReflection(); |
| const Descriptor* descriptor = message.GetDescriptor(); |
| |
| #define f(NAME) descriptor->FindFieldByName(NAME) |
| |
| // Testing every single failure mode would be too much work. Let's just |
| // check a few. |
| EXPECT_DEATH( |
| reflection->GetInt32( |
| message, descriptor->FindFieldByName("optional_int64")), |
| "Protocol Buffer reflection usage error:\n" |
| " Method : google::protobuf::Reflection::GetInt32\n" |
| " Message type: protobuf_unittest\\.TestAllTypes\n" |
| " Field : protobuf_unittest\\.TestAllTypes\\.optional_int64\n" |
| " Problem : Field is not the right type for this message:\n" |
| " Expected : CPPTYPE_INT32\n" |
| " Field type: CPPTYPE_INT64"); |
| EXPECT_DEATH( |
| reflection->GetInt32( |
| message, descriptor->FindFieldByName("repeated_int32")), |
| "Protocol Buffer reflection usage error:\n" |
| " Method : google::protobuf::Reflection::GetInt32\n" |
| " Message type: protobuf_unittest.TestAllTypes\n" |
| " Field : protobuf_unittest.TestAllTypes.repeated_int32\n" |
| " Problem : Field is repeated; the method requires a singular field."); |
| EXPECT_DEATH( |
| reflection->GetInt32( |
| message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")), |
| "Protocol Buffer reflection usage error:\n" |
| " Method : google::protobuf::Reflection::GetInt32\n" |
| " Message type: protobuf_unittest.TestAllTypes\n" |
| " Field : protobuf_unittest.ForeignMessage.c\n" |
| " Problem : Field does not match message type."); |
| EXPECT_DEATH( |
| reflection->HasField( |
| message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")), |
| "Protocol Buffer reflection usage error:\n" |
| " Method : google::protobuf::Reflection::HasField\n" |
| " Message type: protobuf_unittest.TestAllTypes\n" |
| " Field : protobuf_unittest.ForeignMessage.c\n" |
| " Problem : Field does not match message type."); |
| |
| #undef f |
| } |
| |
| #endif // PROTOBUF_HAS_DEATH_TEST |
| |
| |
| } // namespace |
| } // namespace protobuf |
| } // namespace google |