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