1// Protocol Buffers - Google's data interchange format 2// Copyright 2008 Google Inc. All rights reserved. 3// http://code.google.com/p/protobuf/ 4// 5// Redistribution and use in source and binary forms, with or without 6// modification, are permitted provided that the following conditions are 7// met: 8// 9// * Redistributions of source code must retain the above copyright 10// notice, this list of conditions and the following disclaimer. 11// * Redistributions in binary form must reproduce the above 12// copyright notice, this list of conditions and the following disclaimer 13// in the documentation and/or other materials provided with the 14// distribution. 15// * Neither the name of Google Inc. nor the names of its 16// contributors may be used to endorse or promote products derived from 17// this software without specific prior written permission. 18// 19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31// Author: kenton@google.com (Kenton Varda) 32// Based on original Protocol Buffers design by 33// Sanjay Ghemawat, Jeff Dean, and others. 34// 35// To test GeneratedMessageReflection, we actually let the protocol compiler 36// generate a full protocol message implementation and then test its 37// reflection interface. This is much easier and more maintainable than 38// trying to create our own Message class for GeneratedMessageReflection 39// to wrap. 40// 41// The tests here closely mirror some of the tests in 42// compiler/cpp/unittest, except using the reflection interface 43// rather than generated accessors. 44 45#include <google/protobuf/generated_message_reflection.h> 46#include <google/protobuf/descriptor.h> 47#include <google/protobuf/test_util.h> 48#include <google/protobuf/unittest.pb.h> 49 50#include <google/protobuf/stubs/common.h> 51#include <google/protobuf/testing/googletest.h> 52#include <gtest/gtest.h> 53 54namespace google { 55namespace protobuf { 56 57namespace { 58 59// Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes. 60const FieldDescriptor* F(const string& name) { 61 const FieldDescriptor* result = 62 unittest::TestAllTypes::descriptor()->FindFieldByName(name); 63 GOOGLE_CHECK(result != NULL); 64 return result; 65} 66 67TEST(GeneratedMessageReflectionTest, Defaults) { 68 // Check that all default values are set correctly in the initial message. 69 unittest::TestAllTypes message; 70 TestUtil::ReflectionTester reflection_tester( 71 unittest::TestAllTypes::descriptor()); 72 73 reflection_tester.ExpectClearViaReflection(message); 74 75 const Reflection* reflection = message.GetReflection(); 76 77 // Messages should return pointers to default instances until first use. 78 // (This is not checked by ExpectClear() since it is not actually true after 79 // the fields have been set and then cleared.) 80 EXPECT_EQ(&unittest::TestAllTypes::OptionalGroup::default_instance(), 81 &reflection->GetMessage(message, F("optionalgroup"))); 82 EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(), 83 &reflection->GetMessage(message, F("optional_nested_message"))); 84 EXPECT_EQ(&unittest::ForeignMessage::default_instance(), 85 &reflection->GetMessage(message, F("optional_foreign_message"))); 86 EXPECT_EQ(&unittest_import::ImportMessage::default_instance(), 87 &reflection->GetMessage(message, F("optional_import_message"))); 88} 89 90TEST(GeneratedMessageReflectionTest, Accessors) { 91 // Set every field to a unique value then go back and check all those 92 // values. 93 unittest::TestAllTypes message; 94 TestUtil::ReflectionTester reflection_tester( 95 unittest::TestAllTypes::descriptor()); 96 97 reflection_tester.SetAllFieldsViaReflection(&message); 98 TestUtil::ExpectAllFieldsSet(message); 99 reflection_tester.ExpectAllFieldsSetViaReflection(message); 100 101 reflection_tester.ModifyRepeatedFieldsViaReflection(&message); 102 TestUtil::ExpectRepeatedFieldsModified(message); 103} 104 105TEST(GeneratedMessageReflectionTest, GetStringReference) { 106 // Test that GetStringReference() returns the underlying string when it is 107 // a normal string field. 108 unittest::TestAllTypes message; 109 message.set_optional_string("foo"); 110 message.add_repeated_string("foo"); 111 112 const Reflection* reflection = message.GetReflection(); 113 string scratch; 114 115 EXPECT_EQ(&message.optional_string(), 116 &reflection->GetStringReference(message, F("optional_string"), &scratch)) 117 << "For simple string fields, GetStringReference() should return a " 118 "reference to the underlying string."; 119 EXPECT_EQ(&message.repeated_string(0), 120 &reflection->GetRepeatedStringReference(message, F("repeated_string"), 121 0, &scratch)) 122 << "For simple string fields, GetRepeatedStringReference() should return " 123 "a reference to the underlying string."; 124} 125 126 127TEST(GeneratedMessageReflectionTest, DefaultsAfterClear) { 128 // Check that after setting all fields and then clearing, getting an 129 // embedded message does NOT return the default instance. 130 unittest::TestAllTypes message; 131 TestUtil::ReflectionTester reflection_tester( 132 unittest::TestAllTypes::descriptor()); 133 134 TestUtil::SetAllFields(&message); 135 message.Clear(); 136 137 const Reflection* reflection = message.GetReflection(); 138 139 EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(), 140 &reflection->GetMessage(message, F("optionalgroup"))); 141 EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(), 142 &reflection->GetMessage(message, F("optional_nested_message"))); 143 EXPECT_NE(&unittest::ForeignMessage::default_instance(), 144 &reflection->GetMessage(message, F("optional_foreign_message"))); 145 EXPECT_NE(&unittest_import::ImportMessage::default_instance(), 146 &reflection->GetMessage(message, F("optional_import_message"))); 147} 148 149 150TEST(GeneratedMessageReflectionTest, Swap) { 151 unittest::TestAllTypes message1; 152 unittest::TestAllTypes message2; 153 154 TestUtil::SetAllFields(&message1); 155 156 const Reflection* reflection = message1.GetReflection(); 157 reflection->Swap(&message1, &message2); 158 159 TestUtil::ExpectClear(message1); 160 TestUtil::ExpectAllFieldsSet(message2); 161} 162 163TEST(GeneratedMessageReflectionTest, SwapWithBothSet) { 164 unittest::TestAllTypes message1; 165 unittest::TestAllTypes message2; 166 167 TestUtil::SetAllFields(&message1); 168 TestUtil::SetAllFields(&message2); 169 TestUtil::ModifyRepeatedFields(&message2); 170 171 const Reflection* reflection = message1.GetReflection(); 172 reflection->Swap(&message1, &message2); 173 174 TestUtil::ExpectRepeatedFieldsModified(message1); 175 TestUtil::ExpectAllFieldsSet(message2); 176 177 message1.set_optional_int32(532819); 178 179 reflection->Swap(&message1, &message2); 180 181 EXPECT_EQ(532819, message2.optional_int32()); 182} 183 184TEST(GeneratedMessageReflectionTest, SwapExtensions) { 185 unittest::TestAllExtensions message1; 186 unittest::TestAllExtensions message2; 187 188 TestUtil::SetAllExtensions(&message1); 189 190 const Reflection* reflection = message1.GetReflection(); 191 reflection->Swap(&message1, &message2); 192 193 TestUtil::ExpectExtensionsClear(message1); 194 TestUtil::ExpectAllExtensionsSet(message2); 195} 196 197TEST(GeneratedMessageReflectionTest, SwapUnknown) { 198 unittest::TestEmptyMessage message1, message2; 199 200 message1.mutable_unknown_fields()->AddVarint(1234, 1); 201 202 EXPECT_EQ(1, message1.unknown_fields().field_count()); 203 EXPECT_EQ(0, message2.unknown_fields().field_count()); 204 const Reflection* reflection = message1.GetReflection(); 205 reflection->Swap(&message1, &message2); 206 EXPECT_EQ(0, message1.unknown_fields().field_count()); 207 EXPECT_EQ(1, message2.unknown_fields().field_count()); 208} 209 210TEST(GeneratedMessageReflectionTest, RemoveLast) { 211 unittest::TestAllTypes message; 212 TestUtil::ReflectionTester reflection_tester( 213 unittest::TestAllTypes::descriptor()); 214 215 TestUtil::SetAllFields(&message); 216 217 reflection_tester.RemoveLastRepeatedsViaReflection(&message); 218 219 TestUtil::ExpectLastRepeatedsRemoved(message); 220} 221 222TEST(GeneratedMessageReflectionTest, RemoveLastExtensions) { 223 unittest::TestAllExtensions message; 224 TestUtil::ReflectionTester reflection_tester( 225 unittest::TestAllExtensions::descriptor()); 226 227 TestUtil::SetAllExtensions(&message); 228 reflection_tester.RemoveLastRepeatedsViaReflection(&message); 229 230 TestUtil::ExpectLastRepeatedExtensionsRemoved(message); 231} 232 233TEST(GeneratedMessageReflectionTest, SwapRepeatedElements) { 234 unittest::TestAllTypes message; 235 TestUtil::ReflectionTester reflection_tester( 236 unittest::TestAllTypes::descriptor()); 237 238 TestUtil::SetAllFields(&message); 239 240 // Swap and test that fields are all swapped. 241 reflection_tester.SwapRepeatedsViaReflection(&message); 242 TestUtil::ExpectRepeatedsSwapped(message); 243 244 // Swap back and test that fields are all back to original values. 245 reflection_tester.SwapRepeatedsViaReflection(&message); 246 TestUtil::ExpectAllFieldsSet(message); 247} 248 249TEST(GeneratedMessageReflectionTest, SwapRepeatedElementsExtension) { 250 unittest::TestAllExtensions message; 251 TestUtil::ReflectionTester reflection_tester( 252 unittest::TestAllExtensions::descriptor()); 253 254 TestUtil::SetAllExtensions(&message); 255 256 // Swap and test that fields are all swapped. 257 reflection_tester.SwapRepeatedsViaReflection(&message); 258 TestUtil::ExpectRepeatedExtensionsSwapped(message); 259 260 // Swap back and test that fields are all back to original values. 261 reflection_tester.SwapRepeatedsViaReflection(&message); 262 TestUtil::ExpectAllExtensionsSet(message); 263} 264 265TEST(GeneratedMessageReflectionTest, Extensions) { 266 // Set every extension to a unique value then go back and check all those 267 // values. 268 unittest::TestAllExtensions message; 269 TestUtil::ReflectionTester reflection_tester( 270 unittest::TestAllExtensions::descriptor()); 271 272 reflection_tester.SetAllFieldsViaReflection(&message); 273 TestUtil::ExpectAllExtensionsSet(message); 274 reflection_tester.ExpectAllFieldsSetViaReflection(message); 275 276 reflection_tester.ModifyRepeatedFieldsViaReflection(&message); 277 TestUtil::ExpectRepeatedExtensionsModified(message); 278} 279 280TEST(GeneratedMessageReflectionTest, FindExtensionTypeByNumber) { 281 const Reflection* reflection = 282 unittest::TestAllExtensions::default_instance().GetReflection(); 283 284 const FieldDescriptor* extension1 = 285 unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( 286 "optional_int32_extension"); 287 const FieldDescriptor* extension2 = 288 unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( 289 "repeated_string_extension"); 290 291 EXPECT_EQ(extension1, 292 reflection->FindKnownExtensionByNumber(extension1->number())); 293 EXPECT_EQ(extension2, 294 reflection->FindKnownExtensionByNumber(extension2->number())); 295 296 // Non-existent extension. 297 EXPECT_TRUE(reflection->FindKnownExtensionByNumber(62341) == NULL); 298 299 // Extensions of TestAllExtensions should not show up as extensions of 300 // other types. 301 EXPECT_TRUE(unittest::TestAllTypes::default_instance().GetReflection()-> 302 FindKnownExtensionByNumber(extension1->number()) == NULL); 303} 304 305TEST(GeneratedMessageReflectionTest, FindKnownExtensionByName) { 306 const Reflection* reflection = 307 unittest::TestAllExtensions::default_instance().GetReflection(); 308 309 const FieldDescriptor* extension1 = 310 unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( 311 "optional_int32_extension"); 312 const FieldDescriptor* extension2 = 313 unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( 314 "repeated_string_extension"); 315 316 EXPECT_EQ(extension1, 317 reflection->FindKnownExtensionByName(extension1->full_name())); 318 EXPECT_EQ(extension2, 319 reflection->FindKnownExtensionByName(extension2->full_name())); 320 321 // Non-existent extension. 322 EXPECT_TRUE(reflection->FindKnownExtensionByName("no_such_ext") == NULL); 323 324 // Extensions of TestAllExtensions should not show up as extensions of 325 // other types. 326 EXPECT_TRUE(unittest::TestAllTypes::default_instance().GetReflection()-> 327 FindKnownExtensionByName(extension1->full_name()) == NULL); 328} 329 330#ifdef GTEST_HAS_DEATH_TEST 331 332TEST(GeneratedMessageReflectionTest, UsageErrors) { 333 unittest::TestAllTypes message; 334 const Reflection* reflection = message.GetReflection(); 335 const Descriptor* descriptor = message.GetDescriptor(); 336 337#define f(NAME) descriptor->FindFieldByName(NAME) 338 339 // Testing every single failure mode would be too much work. Let's just 340 // check a few. 341 EXPECT_DEATH( 342 reflection->GetInt32( 343 message, descriptor->FindFieldByName("optional_int64")), 344 "Protocol Buffer reflection usage error:\n" 345 " Method : google::protobuf::Reflection::GetInt32\n" 346 " Message type: protobuf_unittest\\.TestAllTypes\n" 347 " Field : protobuf_unittest\\.TestAllTypes\\.optional_int64\n" 348 " Problem : Field is not the right type for this message:\n" 349 " Expected : CPPTYPE_INT32\n" 350 " Field type: CPPTYPE_INT64"); 351 EXPECT_DEATH( 352 reflection->GetInt32( 353 message, descriptor->FindFieldByName("repeated_int32")), 354 "Protocol Buffer reflection usage error:\n" 355 " Method : google::protobuf::Reflection::GetInt32\n" 356 " Message type: protobuf_unittest.TestAllTypes\n" 357 " Field : protobuf_unittest.TestAllTypes.repeated_int32\n" 358 " Problem : Field is repeated; the method requires a singular field."); 359 EXPECT_DEATH( 360 reflection->GetInt32( 361 message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")), 362 "Protocol Buffer reflection usage error:\n" 363 " Method : google::protobuf::Reflection::GetInt32\n" 364 " Message type: protobuf_unittest.TestAllTypes\n" 365 " Field : protobuf_unittest.ForeignMessage.c\n" 366 " Problem : Field does not match message type."); 367 EXPECT_DEATH( 368 reflection->HasField( 369 message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")), 370 "Protocol Buffer reflection usage error:\n" 371 " Method : google::protobuf::Reflection::HasField\n" 372 " Message type: protobuf_unittest.TestAllTypes\n" 373 " Field : protobuf_unittest.ForeignMessage.c\n" 374 " Problem : Field does not match message type."); 375 376#undef f 377} 378 379#endif // GTEST_HAS_DEATH_TEST 380 381 382} // namespace 383} // namespace protobuf 384} // namespace google 385