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 #include <google/protobuf/reflection_ops.h>
36 #include <google/protobuf/descriptor.h>
37 #include <google/protobuf/unittest.pb.h>
38 #include <google/protobuf/test_util.h>
40 #include <google/protobuf/stubs/common.h>
41 #include <google/protobuf/testing/googletest.h>
42 #include <gtest/gtest.h>
43 #include <google/protobuf/stubs/strutil.h>
50 TEST(ReflectionOpsTest, SanityCheck) {
51 unittest::TestAllTypes message;
53 TestUtil::SetAllFields(&message);
54 TestUtil::ExpectAllFieldsSet(message);
57 TEST(ReflectionOpsTest, Copy) {
58 unittest::TestAllTypes message, message2;
60 TestUtil::SetAllFields(&message);
62 ReflectionOps::Copy(message, &message2);
64 TestUtil::ExpectAllFieldsSet(message2);
66 // Copying from self should be a no-op.
67 ReflectionOps::Copy(message2, &message2);
68 TestUtil::ExpectAllFieldsSet(message2);
71 TEST(ReflectionOpsTest, CopyExtensions) {
72 unittest::TestAllExtensions message, message2;
74 TestUtil::SetAllExtensions(&message);
76 ReflectionOps::Copy(message, &message2);
78 TestUtil::ExpectAllExtensionsSet(message2);
81 TEST(ReflectionOpsTest, Merge) {
82 // Note: Copy is implemented in terms of Merge() so technically the Copy
83 // test already tested most of this.
85 unittest::TestAllTypes message, message2;
87 TestUtil::SetAllFields(&message);
89 // This field will test merging into an empty spot.
90 message2.set_optional_int32(message.optional_int32());
91 message.clear_optional_int32();
93 // This tests overwriting.
94 message2.set_optional_string(message.optional_string());
95 message.set_optional_string("something else");
97 // This tests concatenating.
98 message2.add_repeated_int32(message.repeated_int32(1));
99 int32 i = message.repeated_int32(0);
100 message.clear_repeated_int32();
101 message.add_repeated_int32(i);
103 ReflectionOps::Merge(message2, &message);
105 TestUtil::ExpectAllFieldsSet(message);
108 TEST(ReflectionOpsTest, MergeExtensions) {
109 // Note: Copy is implemented in terms of Merge() so technically the Copy
110 // test already tested most of this.
112 unittest::TestAllExtensions message, message2;
114 TestUtil::SetAllExtensions(&message);
116 // This field will test merging into an empty spot.
117 message2.SetExtension(unittest::optional_int32_extension,
118 message.GetExtension(unittest::optional_int32_extension));
119 message.ClearExtension(unittest::optional_int32_extension);
121 // This tests overwriting.
122 message2.SetExtension(unittest::optional_string_extension,
123 message.GetExtension(unittest::optional_string_extension));
124 message.SetExtension(unittest::optional_string_extension, "something else");
126 // This tests concatenating.
127 message2.AddExtension(unittest::repeated_int32_extension,
128 message.GetExtension(unittest::repeated_int32_extension, 1));
129 int32 i = message.GetExtension(unittest::repeated_int32_extension, 0);
130 message.ClearExtension(unittest::repeated_int32_extension);
131 message.AddExtension(unittest::repeated_int32_extension, i);
133 ReflectionOps::Merge(message2, &message);
135 TestUtil::ExpectAllExtensionsSet(message);
138 TEST(ReflectionOpsTest, MergeUnknown) {
139 // Test that the messages' UnknownFieldSets are correctly merged.
140 unittest::TestEmptyMessage message1, message2;
141 message1.mutable_unknown_fields()->AddVarint(1234, 1);
142 message2.mutable_unknown_fields()->AddVarint(1234, 2);
144 ReflectionOps::Merge(message2, &message1);
146 ASSERT_EQ(2, message1.unknown_fields().field_count());
147 ASSERT_EQ(UnknownField::TYPE_VARINT,
148 message1.unknown_fields().field(0).type());
149 EXPECT_EQ(1, message1.unknown_fields().field(0).varint());
150 ASSERT_EQ(UnknownField::TYPE_VARINT,
151 message1.unknown_fields().field(1).type());
152 EXPECT_EQ(2, message1.unknown_fields().field(1).varint());
155 #ifdef PROTOBUF_HAS_DEATH_TEST
157 TEST(ReflectionOpsTest, MergeFromSelf) {
158 // Note: Copy is implemented in terms of Merge() so technically the Copy
159 // test already tested most of this.
161 unittest::TestAllTypes message;
164 ReflectionOps::Merge(message, &message),
168 #endif // PROTOBUF_HAS_DEATH_TEST
170 TEST(ReflectionOpsTest, Clear) {
171 unittest::TestAllTypes message;
173 TestUtil::SetAllFields(&message);
175 ReflectionOps::Clear(&message);
177 TestUtil::ExpectClear(message);
179 // Check that getting embedded messages returns the objects created during
180 // SetAllFields() rather than default instances.
181 EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(),
182 &message.optionalgroup());
183 EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
184 &message.optional_nested_message());
185 EXPECT_NE(&unittest::ForeignMessage::default_instance(),
186 &message.optional_foreign_message());
187 EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
188 &message.optional_import_message());
191 TEST(ReflectionOpsTest, ClearExtensions) {
192 unittest::TestAllExtensions message;
194 TestUtil::SetAllExtensions(&message);
196 ReflectionOps::Clear(&message);
198 TestUtil::ExpectExtensionsClear(message);
200 // Check that getting embedded messages returns the objects created during
201 // SetAllExtensions() rather than default instances.
202 EXPECT_NE(&unittest::OptionalGroup_extension::default_instance(),
203 &message.GetExtension(unittest::optionalgroup_extension));
204 EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
205 &message.GetExtension(unittest::optional_nested_message_extension));
206 EXPECT_NE(&unittest::ForeignMessage::default_instance(),
207 &message.GetExtension(
208 unittest::optional_foreign_message_extension));
209 EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
210 &message.GetExtension(unittest::optional_import_message_extension));
213 TEST(ReflectionOpsTest, ClearUnknown) {
214 // Test that the message's UnknownFieldSet is correctly cleared.
215 unittest::TestEmptyMessage message;
216 message.mutable_unknown_fields()->AddVarint(1234, 1);
218 ReflectionOps::Clear(&message);
220 EXPECT_EQ(0, message.unknown_fields().field_count());
223 TEST(ReflectionOpsTest, DiscardUnknownFields) {
224 unittest::TestAllTypes message;
225 TestUtil::SetAllFields(&message);
227 // Set some unknown fields in message.
228 message.mutable_unknown_fields()
229 ->AddVarint(123456, 654321);
230 message.mutable_optional_nested_message()
231 ->mutable_unknown_fields()
232 ->AddVarint(123456, 654321);
233 message.mutable_repeated_nested_message(0)
234 ->mutable_unknown_fields()
235 ->AddVarint(123456, 654321);
237 EXPECT_EQ(1, message.unknown_fields().field_count());
238 EXPECT_EQ(1, message.optional_nested_message()
239 .unknown_fields().field_count());
240 EXPECT_EQ(1, message.repeated_nested_message(0)
241 .unknown_fields().field_count());
244 ReflectionOps::DiscardUnknownFields(&message);
245 TestUtil::ExpectAllFieldsSet(message);
247 EXPECT_EQ(0, message.unknown_fields().field_count());
248 EXPECT_EQ(0, message.optional_nested_message()
249 .unknown_fields().field_count());
250 EXPECT_EQ(0, message.repeated_nested_message(0)
251 .unknown_fields().field_count());
254 TEST(ReflectionOpsTest, DiscardUnknownExtensions) {
255 unittest::TestAllExtensions message;
256 TestUtil::SetAllExtensions(&message);
258 // Set some unknown fields.
259 message.mutable_unknown_fields()
260 ->AddVarint(123456, 654321);
261 message.MutableExtension(unittest::optional_nested_message_extension)
262 ->mutable_unknown_fields()
263 ->AddVarint(123456, 654321);
264 message.MutableExtension(unittest::repeated_nested_message_extension, 0)
265 ->mutable_unknown_fields()
266 ->AddVarint(123456, 654321);
268 EXPECT_EQ(1, message.unknown_fields().field_count());
270 message.GetExtension(unittest::optional_nested_message_extension)
271 .unknown_fields().field_count());
273 message.GetExtension(unittest::repeated_nested_message_extension, 0)
274 .unknown_fields().field_count());
277 ReflectionOps::DiscardUnknownFields(&message);
278 TestUtil::ExpectAllExtensionsSet(message);
280 EXPECT_EQ(0, message.unknown_fields().field_count());
282 message.GetExtension(unittest::optional_nested_message_extension)
283 .unknown_fields().field_count());
285 message.GetExtension(unittest::repeated_nested_message_extension, 0)
286 .unknown_fields().field_count());
289 TEST(ReflectionOpsTest, IsInitialized) {
290 unittest::TestRequired message;
292 EXPECT_FALSE(ReflectionOps::IsInitialized(message));
294 EXPECT_FALSE(ReflectionOps::IsInitialized(message));
296 EXPECT_FALSE(ReflectionOps::IsInitialized(message));
298 EXPECT_TRUE(ReflectionOps::IsInitialized(message));
301 TEST(ReflectionOpsTest, ForeignIsInitialized) {
302 unittest::TestRequiredForeign message;
304 // Starts out initialized because the foreign message is itself an optional
306 EXPECT_TRUE(ReflectionOps::IsInitialized(message));
308 // Once we create that field, the message is no longer initialized.
309 message.mutable_optional_message();
310 EXPECT_FALSE(ReflectionOps::IsInitialized(message));
312 // Initialize it. Now we're initialized.
313 message.mutable_optional_message()->set_a(1);
314 message.mutable_optional_message()->set_b(2);
315 message.mutable_optional_message()->set_c(3);
316 EXPECT_TRUE(ReflectionOps::IsInitialized(message));
318 // Add a repeated version of the message. No longer initialized.
319 unittest::TestRequired* sub_message = message.add_repeated_message();
320 EXPECT_FALSE(ReflectionOps::IsInitialized(message));
322 // Initialize that repeated version.
323 sub_message->set_a(1);
324 sub_message->set_b(2);
325 sub_message->set_c(3);
326 EXPECT_TRUE(ReflectionOps::IsInitialized(message));
329 TEST(ReflectionOpsTest, ExtensionIsInitialized) {
330 unittest::TestAllExtensions message;
332 // Starts out initialized because the foreign message is itself an optional
334 EXPECT_TRUE(ReflectionOps::IsInitialized(message));
336 // Once we create that field, the message is no longer initialized.
337 message.MutableExtension(unittest::TestRequired::single);
338 EXPECT_FALSE(ReflectionOps::IsInitialized(message));
340 // Initialize it. Now we're initialized.
341 message.MutableExtension(unittest::TestRequired::single)->set_a(1);
342 message.MutableExtension(unittest::TestRequired::single)->set_b(2);
343 message.MutableExtension(unittest::TestRequired::single)->set_c(3);
344 EXPECT_TRUE(ReflectionOps::IsInitialized(message));
346 // Add a repeated version of the message. No longer initialized.
347 message.AddExtension(unittest::TestRequired::multi);
348 EXPECT_FALSE(ReflectionOps::IsInitialized(message));
350 // Initialize that repeated version.
351 message.MutableExtension(unittest::TestRequired::multi, 0)->set_a(1);
352 message.MutableExtension(unittest::TestRequired::multi, 0)->set_b(2);
353 message.MutableExtension(unittest::TestRequired::multi, 0)->set_c(3);
354 EXPECT_TRUE(ReflectionOps::IsInitialized(message));
357 static string FindInitializationErrors(const Message& message) {
358 vector<string> errors;
359 ReflectionOps::FindInitializationErrors(message, "", &errors);
360 return JoinStrings(errors, ",");
363 TEST(ReflectionOpsTest, FindInitializationErrors) {
364 unittest::TestRequired message;
365 EXPECT_EQ("a,b,c", FindInitializationErrors(message));
368 TEST(ReflectionOpsTest, FindForeignInitializationErrors) {
369 unittest::TestRequiredForeign message;
370 message.mutable_optional_message();
371 message.add_repeated_message();
372 message.add_repeated_message();
373 EXPECT_EQ("optional_message.a,"
374 "optional_message.b,"
375 "optional_message.c,"
376 "repeated_message[0].a,"
377 "repeated_message[0].b,"
378 "repeated_message[0].c,"
379 "repeated_message[1].a,"
380 "repeated_message[1].b,"
381 "repeated_message[1].c",
382 FindInitializationErrors(message));
385 TEST(ReflectionOpsTest, FindExtensionInitializationErrors) {
386 unittest::TestAllExtensions message;
387 message.MutableExtension(unittest::TestRequired::single);
388 message.AddExtension(unittest::TestRequired::multi);
389 message.AddExtension(unittest::TestRequired::multi);
390 EXPECT_EQ("(protobuf_unittest.TestRequired.single).a,"
391 "(protobuf_unittest.TestRequired.single).b,"
392 "(protobuf_unittest.TestRequired.single).c,"
393 "(protobuf_unittest.TestRequired.multi)[0].a,"
394 "(protobuf_unittest.TestRequired.multi)[0].b,"
395 "(protobuf_unittest.TestRequired.multi)[0].c,"
396 "(protobuf_unittest.TestRequired.multi)[1].a,"
397 "(protobuf_unittest.TestRequired.multi)[1].b,"
398 "(protobuf_unittest.TestRequired.multi)[1].c",
399 FindInitializationErrors(message));
403 } // namespace internal
404 } // namespace protobuf
405 } // namespace google