1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // http://code.google.com/p/protobuf/
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
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
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.
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.
31 // Author: kenton@google.com (Kenton Varda)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
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
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.
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>
50 #include <google/protobuf/stubs/common.h>
51 #include <google/protobuf/testing/googletest.h>
52 #include <gtest/gtest.h>
59 // Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes.
60 const FieldDescriptor* F(const string& name) {
61 const FieldDescriptor* result =
62 unittest::TestAllTypes::descriptor()->FindFieldByName(name);
63 GOOGLE_CHECK(result != NULL);
67 TEST(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());
73 reflection_tester.ExpectClearViaReflection(message);
75 const Reflection* reflection = message.GetReflection();
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")));
90 TEST(GeneratedMessageReflectionTest, Accessors) {
91 // Set every field to a unique value then go back and check all those
93 unittest::TestAllTypes message;
94 TestUtil::ReflectionTester reflection_tester(
95 unittest::TestAllTypes::descriptor());
97 reflection_tester.SetAllFieldsViaReflection(&message);
98 TestUtil::ExpectAllFieldsSet(message);
99 reflection_tester.ExpectAllFieldsSetViaReflection(message);
101 reflection_tester.ModifyRepeatedFieldsViaReflection(&message);
102 TestUtil::ExpectRepeatedFieldsModified(message);
105 TEST(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");
112 const Reflection* reflection = message.GetReflection();
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"),
122 << "For simple string fields, GetRepeatedStringReference() should return "
123 "a reference to the underlying string.";
127 TEST(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());
134 TestUtil::SetAllFields(&message);
137 const Reflection* reflection = message.GetReflection();
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")));
150 TEST(GeneratedMessageReflectionTest, Swap) {
151 unittest::TestAllTypes message1;
152 unittest::TestAllTypes message2;
154 TestUtil::SetAllFields(&message1);
156 const Reflection* reflection = message1.GetReflection();
157 reflection->Swap(&message1, &message2);
159 TestUtil::ExpectClear(message1);
160 TestUtil::ExpectAllFieldsSet(message2);
163 TEST(GeneratedMessageReflectionTest, SwapWithBothSet) {
164 unittest::TestAllTypes message1;
165 unittest::TestAllTypes message2;
167 TestUtil::SetAllFields(&message1);
168 TestUtil::SetAllFields(&message2);
169 TestUtil::ModifyRepeatedFields(&message2);
171 const Reflection* reflection = message1.GetReflection();
172 reflection->Swap(&message1, &message2);
174 TestUtil::ExpectRepeatedFieldsModified(message1);
175 TestUtil::ExpectAllFieldsSet(message2);
177 message1.set_optional_int32(532819);
179 reflection->Swap(&message1, &message2);
181 EXPECT_EQ(532819, message2.optional_int32());
184 TEST(GeneratedMessageReflectionTest, SwapExtensions) {
185 unittest::TestAllExtensions message1;
186 unittest::TestAllExtensions message2;
188 TestUtil::SetAllExtensions(&message1);
190 const Reflection* reflection = message1.GetReflection();
191 reflection->Swap(&message1, &message2);
193 TestUtil::ExpectExtensionsClear(message1);
194 TestUtil::ExpectAllExtensionsSet(message2);
197 TEST(GeneratedMessageReflectionTest, SwapUnknown) {
198 unittest::TestEmptyMessage message1, message2;
200 message1.mutable_unknown_fields()->AddVarint(1234, 1);
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());
210 TEST(GeneratedMessageReflectionTest, RemoveLast) {
211 unittest::TestAllTypes message;
212 TestUtil::ReflectionTester reflection_tester(
213 unittest::TestAllTypes::descriptor());
215 TestUtil::SetAllFields(&message);
217 reflection_tester.RemoveLastRepeatedsViaReflection(&message);
219 TestUtil::ExpectLastRepeatedsRemoved(message);
222 TEST(GeneratedMessageReflectionTest, RemoveLastExtensions) {
223 unittest::TestAllExtensions message;
224 TestUtil::ReflectionTester reflection_tester(
225 unittest::TestAllExtensions::descriptor());
227 TestUtil::SetAllExtensions(&message);
229 reflection_tester.RemoveLastRepeatedsViaReflection(&message);
231 TestUtil::ExpectLastRepeatedExtensionsRemoved(message);
234 TEST(GeneratedMessageReflectionTest, ReleaseLast) {
235 unittest::TestAllTypes message;
236 const Descriptor* descriptor = message.GetDescriptor();
237 TestUtil::ReflectionTester reflection_tester(descriptor);
239 TestUtil::SetAllFields(&message);
241 reflection_tester.ReleaseLastRepeatedsViaReflection(&message, false);
243 TestUtil::ExpectLastRepeatedsReleased(message);
245 // Now test that we actually release the right message.
247 TestUtil::SetAllFields(&message);
248 ASSERT_EQ(2, message.repeated_foreign_message_size());
249 const protobuf_unittest::ForeignMessage* expected =
250 message.mutable_repeated_foreign_message(1);
251 scoped_ptr<Message> released(message.GetReflection()->ReleaseLast(
252 &message, descriptor->FindFieldByName("repeated_foreign_message")));
253 EXPECT_EQ(expected, released.get());
256 TEST(GeneratedMessageReflectionTest, ReleaseLastExtensions) {
257 unittest::TestAllExtensions message;
258 const Descriptor* descriptor = message.GetDescriptor();
259 TestUtil::ReflectionTester reflection_tester(descriptor);
261 TestUtil::SetAllExtensions(&message);
263 reflection_tester.ReleaseLastRepeatedsViaReflection(&message, true);
265 TestUtil::ExpectLastRepeatedExtensionsReleased(message);
267 // Now test that we actually release the right message.
269 TestUtil::SetAllExtensions(&message);
270 ASSERT_EQ(2, message.ExtensionSize(
271 unittest::repeated_foreign_message_extension));
272 const protobuf_unittest::ForeignMessage* expected = message.MutableExtension(
273 unittest::repeated_foreign_message_extension, 1);
274 scoped_ptr<Message> released(message.GetReflection()->ReleaseLast(
275 &message, descriptor->file()->FindExtensionByName(
276 "repeated_foreign_message_extension")));
277 EXPECT_EQ(expected, released.get());
281 TEST(GeneratedMessageReflectionTest, SwapRepeatedElements) {
282 unittest::TestAllTypes message;
283 TestUtil::ReflectionTester reflection_tester(
284 unittest::TestAllTypes::descriptor());
286 TestUtil::SetAllFields(&message);
288 // Swap and test that fields are all swapped.
289 reflection_tester.SwapRepeatedsViaReflection(&message);
290 TestUtil::ExpectRepeatedsSwapped(message);
292 // Swap back and test that fields are all back to original values.
293 reflection_tester.SwapRepeatedsViaReflection(&message);
294 TestUtil::ExpectAllFieldsSet(message);
297 TEST(GeneratedMessageReflectionTest, SwapRepeatedElementsExtension) {
298 unittest::TestAllExtensions message;
299 TestUtil::ReflectionTester reflection_tester(
300 unittest::TestAllExtensions::descriptor());
302 TestUtil::SetAllExtensions(&message);
304 // Swap and test that fields are all swapped.
305 reflection_tester.SwapRepeatedsViaReflection(&message);
306 TestUtil::ExpectRepeatedExtensionsSwapped(message);
308 // Swap back and test that fields are all back to original values.
309 reflection_tester.SwapRepeatedsViaReflection(&message);
310 TestUtil::ExpectAllExtensionsSet(message);
313 TEST(GeneratedMessageReflectionTest, Extensions) {
314 // Set every extension to a unique value then go back and check all those
316 unittest::TestAllExtensions message;
317 TestUtil::ReflectionTester reflection_tester(
318 unittest::TestAllExtensions::descriptor());
320 reflection_tester.SetAllFieldsViaReflection(&message);
321 TestUtil::ExpectAllExtensionsSet(message);
322 reflection_tester.ExpectAllFieldsSetViaReflection(message);
324 reflection_tester.ModifyRepeatedFieldsViaReflection(&message);
325 TestUtil::ExpectRepeatedExtensionsModified(message);
328 TEST(GeneratedMessageReflectionTest, FindExtensionTypeByNumber) {
329 const Reflection* reflection =
330 unittest::TestAllExtensions::default_instance().GetReflection();
332 const FieldDescriptor* extension1 =
333 unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName(
334 "optional_int32_extension");
335 const FieldDescriptor* extension2 =
336 unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName(
337 "repeated_string_extension");
339 EXPECT_EQ(extension1,
340 reflection->FindKnownExtensionByNumber(extension1->number()));
341 EXPECT_EQ(extension2,
342 reflection->FindKnownExtensionByNumber(extension2->number()));
344 // Non-existent extension.
345 EXPECT_TRUE(reflection->FindKnownExtensionByNumber(62341) == NULL);
347 // Extensions of TestAllExtensions should not show up as extensions of
349 EXPECT_TRUE(unittest::TestAllTypes::default_instance().GetReflection()->
350 FindKnownExtensionByNumber(extension1->number()) == NULL);
353 TEST(GeneratedMessageReflectionTest, FindKnownExtensionByName) {
354 const Reflection* reflection =
355 unittest::TestAllExtensions::default_instance().GetReflection();
357 const FieldDescriptor* extension1 =
358 unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName(
359 "optional_int32_extension");
360 const FieldDescriptor* extension2 =
361 unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName(
362 "repeated_string_extension");
364 EXPECT_EQ(extension1,
365 reflection->FindKnownExtensionByName(extension1->full_name()));
366 EXPECT_EQ(extension2,
367 reflection->FindKnownExtensionByName(extension2->full_name()));
369 // Non-existent extension.
370 EXPECT_TRUE(reflection->FindKnownExtensionByName("no_such_ext") == NULL);
372 // Extensions of TestAllExtensions should not show up as extensions of
374 EXPECT_TRUE(unittest::TestAllTypes::default_instance().GetReflection()->
375 FindKnownExtensionByName(extension1->full_name()) == NULL);
378 TEST(GeneratedMessageReflectionTest, ReleaseMessageTest) {
379 unittest::TestAllTypes message;
380 TestUtil::ReflectionTester reflection_tester(
381 unittest::TestAllTypes::descriptor());
383 // When nothing is set, we expect all released messages to be NULL.
384 reflection_tester.ExpectMessagesReleasedViaReflection(
385 &message, TestUtil::ReflectionTester::IS_NULL);
387 // After fields are set we should get non-NULL releases.
388 reflection_tester.SetAllFieldsViaReflection(&message);
389 reflection_tester.ExpectMessagesReleasedViaReflection(
390 &message, TestUtil::ReflectionTester::NOT_NULL);
392 // After Clear() we may or may not get a message from ReleaseMessage().
393 // This is implementation specific.
394 reflection_tester.SetAllFieldsViaReflection(&message);
396 reflection_tester.ExpectMessagesReleasedViaReflection(
397 &message, TestUtil::ReflectionTester::CAN_BE_NULL);
399 // Test a different code path for setting after releasing.
400 TestUtil::SetAllFields(&message);
401 TestUtil::ExpectAllFieldsSet(message);
404 TEST(GeneratedMessageReflectionTest, ReleaseExtensionMessageTest) {
405 unittest::TestAllExtensions message;
406 TestUtil::ReflectionTester reflection_tester(
407 unittest::TestAllExtensions::descriptor());
409 // When nothing is set, we expect all released messages to be NULL.
410 reflection_tester.ExpectMessagesReleasedViaReflection(
411 &message, TestUtil::ReflectionTester::IS_NULL);
413 // After fields are set we should get non-NULL releases.
414 reflection_tester.SetAllFieldsViaReflection(&message);
415 reflection_tester.ExpectMessagesReleasedViaReflection(
416 &message, TestUtil::ReflectionTester::NOT_NULL);
418 // After Clear() we may or may not get a message from ReleaseMessage().
419 // This is implementation specific.
420 reflection_tester.SetAllFieldsViaReflection(&message);
422 reflection_tester.ExpectMessagesReleasedViaReflection(
423 &message, TestUtil::ReflectionTester::CAN_BE_NULL);
425 // Test a different code path for setting after releasing.
426 TestUtil::SetAllExtensions(&message);
427 TestUtil::ExpectAllExtensionsSet(message);
430 #ifdef PROTOBUF_HAS_DEATH_TEST
432 TEST(GeneratedMessageReflectionTest, UsageErrors) {
433 unittest::TestAllTypes message;
434 const Reflection* reflection = message.GetReflection();
435 const Descriptor* descriptor = message.GetDescriptor();
437 #define f(NAME) descriptor->FindFieldByName(NAME)
439 // Testing every single failure mode would be too much work. Let's just
442 reflection->GetInt32(
443 message, descriptor->FindFieldByName("optional_int64")),
444 "Protocol Buffer reflection usage error:\n"
445 " Method : google::protobuf::Reflection::GetInt32\n"
446 " Message type: protobuf_unittest\\.TestAllTypes\n"
447 " Field : protobuf_unittest\\.TestAllTypes\\.optional_int64\n"
448 " Problem : Field is not the right type for this message:\n"
449 " Expected : CPPTYPE_INT32\n"
450 " Field type: CPPTYPE_INT64");
452 reflection->GetInt32(
453 message, descriptor->FindFieldByName("repeated_int32")),
454 "Protocol Buffer reflection usage error:\n"
455 " Method : google::protobuf::Reflection::GetInt32\n"
456 " Message type: protobuf_unittest.TestAllTypes\n"
457 " Field : protobuf_unittest.TestAllTypes.repeated_int32\n"
458 " Problem : Field is repeated; the method requires a singular field.");
460 reflection->GetInt32(
461 message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")),
462 "Protocol Buffer reflection usage error:\n"
463 " Method : google::protobuf::Reflection::GetInt32\n"
464 " Message type: protobuf_unittest.TestAllTypes\n"
465 " Field : protobuf_unittest.ForeignMessage.c\n"
466 " Problem : Field does not match message type.");
468 reflection->HasField(
469 message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")),
470 "Protocol Buffer reflection usage error:\n"
471 " Method : google::protobuf::Reflection::HasField\n"
472 " Message type: protobuf_unittest.TestAllTypes\n"
473 " Field : protobuf_unittest.ForeignMessage.c\n"
474 " Problem : Field does not match message type.");
479 #endif // PROTOBUF_HAS_DEATH_TEST
483 } // namespace protobuf
484 } // namespace google