Home | History | Annotate | Download | only in protobuf
      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 (at) google.com (Kenton Varda)
     32 //  Based on original Protocol Buffers design by
     33 //  Sanjay Ghemawat, Jeff Dean, and others.
     34 //
     35 // Since the reflection interface for DynamicMessage is implemented by
     36 // GenericMessageReflection, the only thing we really have to test is
     37 // that DynamicMessage correctly sets up the information that
     38 // GenericMessageReflection needs to use.  So, we focus on that in this
     39 // test.  Other tests, such as generic_message_reflection_unittest and
     40 // reflection_ops_unittest, cover the rest of the functionality used by
     41 // DynamicMessage.
     42 
     43 #include <google/protobuf/stubs/common.h>
     44 #include <google/protobuf/dynamic_message.h>
     45 #include <google/protobuf/descriptor.h>
     46 #include <google/protobuf/descriptor.pb.h>
     47 #include <google/protobuf/test_util.h>
     48 #include <google/protobuf/unittest.pb.h>
     49 
     50 #include <google/protobuf/testing/googletest.h>
     51 #include <gtest/gtest.h>
     52 
     53 namespace google {
     54 namespace protobuf {
     55 
     56 class DynamicMessageTest : public testing::Test {
     57  protected:
     58   DescriptorPool pool_;
     59   DynamicMessageFactory factory_;
     60   const Descriptor* descriptor_;
     61   const Message* prototype_;
     62   const Descriptor* extensions_descriptor_;
     63   const Message* extensions_prototype_;
     64   const Descriptor* packed_descriptor_;
     65   const Message* packed_prototype_;
     66 
     67   DynamicMessageTest(): factory_(&pool_) {}
     68 
     69   virtual void SetUp() {
     70     // We want to make sure that DynamicMessage works (particularly with
     71     // extensions) even if we use descriptors that are *not* from compiled-in
     72     // types, so we make copies of the descriptors for unittest.proto and
     73     // unittest_import.proto.
     74     FileDescriptorProto unittest_file;
     75     FileDescriptorProto unittest_import_file;
     76 
     77     unittest::TestAllTypes::descriptor()->file()->CopyTo(&unittest_file);
     78     unittest_import::ImportMessage::descriptor()->file()->CopyTo(
     79       &unittest_import_file);
     80 
     81     ASSERT_TRUE(pool_.BuildFile(unittest_import_file) != NULL);
     82     ASSERT_TRUE(pool_.BuildFile(unittest_file) != NULL);
     83 
     84     descriptor_ = pool_.FindMessageTypeByName("protobuf_unittest.TestAllTypes");
     85     ASSERT_TRUE(descriptor_ != NULL);
     86     prototype_ = factory_.GetPrototype(descriptor_);
     87 
     88     extensions_descriptor_ =
     89       pool_.FindMessageTypeByName("protobuf_unittest.TestAllExtensions");
     90     ASSERT_TRUE(extensions_descriptor_ != NULL);
     91     extensions_prototype_ = factory_.GetPrototype(extensions_descriptor_);
     92 
     93     packed_descriptor_ =
     94       pool_.FindMessageTypeByName("protobuf_unittest.TestPackedTypes");
     95     ASSERT_TRUE(packed_descriptor_ != NULL);
     96     packed_prototype_ = factory_.GetPrototype(packed_descriptor_);
     97   }
     98 };
     99 
    100 TEST_F(DynamicMessageTest, Descriptor) {
    101   // Check that the descriptor on the DynamicMessage matches the descriptor
    102   // passed to GetPrototype().
    103   EXPECT_EQ(prototype_->GetDescriptor(), descriptor_);
    104 }
    105 
    106 TEST_F(DynamicMessageTest, OnePrototype) {
    107   // Check that requesting the same prototype twice produces the same object.
    108   EXPECT_EQ(prototype_, factory_.GetPrototype(descriptor_));
    109 }
    110 
    111 TEST_F(DynamicMessageTest, Defaults) {
    112   // Check that all default values are set correctly in the initial message.
    113   TestUtil::ReflectionTester reflection_tester(descriptor_);
    114   reflection_tester.ExpectClearViaReflection(*prototype_);
    115 }
    116 
    117 TEST_F(DynamicMessageTest, IndependentOffsets) {
    118   // Check that all fields have independent offsets by setting each
    119   // one to a unique value then checking that they all still have those
    120   // unique values (i.e. they don't stomp each other).
    121   scoped_ptr<Message> message(prototype_->New());
    122   TestUtil::ReflectionTester reflection_tester(descriptor_);
    123 
    124   reflection_tester.SetAllFieldsViaReflection(message.get());
    125   reflection_tester.ExpectAllFieldsSetViaReflection(*message);
    126 }
    127 
    128 TEST_F(DynamicMessageTest, Extensions) {
    129   // Check that extensions work.
    130   scoped_ptr<Message> message(extensions_prototype_->New());
    131   TestUtil::ReflectionTester reflection_tester(extensions_descriptor_);
    132 
    133   reflection_tester.SetAllFieldsViaReflection(message.get());
    134   reflection_tester.ExpectAllFieldsSetViaReflection(*message);
    135 }
    136 
    137 TEST_F(DynamicMessageTest, PackedFields) {
    138   // Check that packed fields work properly.
    139   scoped_ptr<Message> message(packed_prototype_->New());
    140   TestUtil::ReflectionTester reflection_tester(packed_descriptor_);
    141 
    142   reflection_tester.SetPackedFieldsViaReflection(message.get());
    143   reflection_tester.ExpectPackedFieldsSetViaReflection(*message);
    144 }
    145 
    146 TEST_F(DynamicMessageTest, SpaceUsed) {
    147   // Test that SpaceUsed() works properly
    148 
    149   // Since we share the implementation with generated messages, we don't need
    150   // to test very much here.  Just make sure it appears to be working.
    151 
    152   scoped_ptr<Message> message(prototype_->New());
    153   TestUtil::ReflectionTester reflection_tester(descriptor_);
    154 
    155   int initial_space_used = message->SpaceUsed();
    156 
    157   reflection_tester.SetAllFieldsViaReflection(message.get());
    158   EXPECT_LT(initial_space_used, message->SpaceUsed());
    159 }
    160 
    161 }  // namespace protobuf
    162 }  // namespace google
    163