aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/compiler/cpp/cpp_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/google/protobuf/compiler/cpp/cpp_unittest.cc')
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_unittest.cc140
1 files changed, 136 insertions, 4 deletions
diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
index c7e4ee3d..ea9cc32d 100644
--- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
@@ -52,6 +52,8 @@
#include <google/protobuf/test_util.h>
#include <google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.h>
#include <google/protobuf/compiler/importer.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/dynamic_message.h>
@@ -61,6 +63,7 @@
#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
namespace google {
namespace protobuf {
@@ -86,6 +89,8 @@ class MockErrorCollector : public MultiFileErrorCollector {
}
};
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+
// Test that generated code has proper descriptors:
// Parse a descriptor directly (using google::protobuf::compiler::Importer) and
// compare it to the one that was produced by generated code.
@@ -115,6 +120,8 @@ TEST(GeneratedDescriptorTest, IdenticalDescriptors) {
generated_decsriptor_proto.DebugString());
}
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+
// ===================================================================
TEST(GeneratedMessageTest, Defaults) {
@@ -222,6 +229,22 @@ TEST(GeneratedMessageTest, ClearOneField) {
TestUtil::ExpectAllFieldsSet(message);
}
+TEST(GeneratedMessageTest, StringCharStarLength) {
+ // Verify that we can use a char*,length to set one of the string fields.
+ unittest::TestAllTypes message;
+ message.set_optional_string("abcdef", 3);
+ EXPECT_EQ("abc", message.optional_string());
+
+ // Verify that we can use a char*,length to add to a repeated string field.
+ message.add_repeated_string("abcdef", 3);
+ EXPECT_EQ(1, message.repeated_string_size());
+ EXPECT_EQ("abc", message.repeated_string(0));
+
+ // Verify that we can use a char*,length to set a repeated string field.
+ message.set_repeated_string(0, "wxyz", 2);
+ EXPECT_EQ("wx", message.repeated_string(0));
+}
+
TEST(GeneratedMessageTest, CopyFrom) {
unittest::TestAllTypes message1, message2;
@@ -346,6 +369,8 @@ TEST(GeneratedMessageTest, UpcastCopyFrom) {
TestUtil::ExpectAllFieldsSet(message2);
}
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+
TEST(GeneratedMessageTest, DynamicMessageCopyFrom) {
// Test copying from a DynamicMessage, which must fall back to using
// reflection.
@@ -366,6 +391,8 @@ TEST(GeneratedMessageTest, DynamicMessageCopyFrom) {
TestUtil::ExpectAllFieldsSet(message2);
}
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+
TEST(GeneratedMessageTest, NonEmptyMergeFrom) {
// Test merging with a non-empty message. Code is a modified form
// of that found in google/protobuf/reflection_ops_unittest.cc.
@@ -403,24 +430,75 @@ TEST(GeneratedMessageTest, MergeFromSelf) {
#endif // GTEST_HAS_DEATH_TEST
-TEST(GeneratedMessageTest, Serialization) {
+// Test the generated SerializeWithCachedSizesToArray(),
+TEST(GeneratedMessageTest, SerializationToArray) {
unittest::TestAllTypes message1, message2;
string data;
-
TestUtil::SetAllFields(&message1);
- message1.SerializeToString(&data);
+ int size = message1.ByteSize();
+ data.resize(size);
+ uint8* start = reinterpret_cast<uint8*>(string_as_array(&data));
+ uint8* end =
+ message1.TestAllTypes::SerializeWithCachedSizesToArray(start);
+ EXPECT_EQ(size, end - start);
EXPECT_TRUE(message2.ParseFromString(data));
TestUtil::ExpectAllFieldsSet(message2);
+}
+TEST(GeneratedMessageTest, PackedFieldsSerializationToArray) {
unittest::TestPackedTypes packed_message1, packed_message2;
string packed_data;
TestUtil::SetPackedFields(&packed_message1);
- packed_message1.SerializeToString(&packed_data);
+ int packed_size = packed_message1.ByteSize();
+ packed_data.resize(packed_size);
+ uint8* start = reinterpret_cast<uint8*>(string_as_array(&packed_data));
+ uint8* end =
+ packed_message1.TestPackedTypes::SerializeWithCachedSizesToArray(start);
+ EXPECT_EQ(packed_size, end - start);
EXPECT_TRUE(packed_message2.ParseFromString(packed_data));
TestUtil::ExpectPackedFieldsSet(packed_message2);
}
+// Test the generated SerializeWithCachedSizes() by forcing the buffer to write
+// one byte at a time.
+TEST(GeneratedMessageTest, SerializationToStream) {
+ unittest::TestAllTypes message1, message2;
+ TestUtil::SetAllFields(&message1);
+ int size = message1.ByteSize();
+ string data;
+ data.resize(size);
+ {
+ // Allow the output stream to buffer only one byte at a time.
+ io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ message1.TestAllTypes::SerializeWithCachedSizes(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ }
+ EXPECT_TRUE(message2.ParseFromString(data));
+ TestUtil::ExpectAllFieldsSet(message2);
+
+}
+
+TEST(GeneratedMessageTest, PackedFieldsSerializationToStream) {
+ unittest::TestPackedTypes message1, message2;
+ TestUtil::SetPackedFields(&message1);
+ int size = message1.ByteSize();
+ string data;
+ data.resize(size);
+ {
+ // Allow the output stream to buffer only one byte at a time.
+ io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ message1.TestPackedTypes::SerializeWithCachedSizes(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ }
+ EXPECT_TRUE(message2.ParseFromString(data));
+ TestUtil::ExpectPackedFieldsSet(message2);
+}
+
TEST(GeneratedMessageTest, Required) {
// Test that IsInitialized() returns false if required fields are missing.
@@ -547,6 +625,8 @@ TEST(GeneratedMessageTest, TestConflictingSymbolNames) {
EXPECT_EQ(5, message.friend_());
}
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+
TEST(GeneratedMessageTest, TestOptimizedForSize) {
// We rely on the tests in reflection_ops_unittest and wire_format_unittest
// to really test that reflection-based methods work. Here we are mostly
@@ -614,6 +694,8 @@ TEST(GeneratedMessageTest, TestSpaceUsed) {
message1.SpaceUsed());
}
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+
// ===================================================================
TEST(GeneratedEnumTest, EnumValuesAsSwitchCases) {
@@ -682,8 +764,37 @@ TEST(GeneratedEnumTest, MinAndMax) {
}
}
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+
+TEST(GeneratedEnumTest, Name) {
+ // "Names" in the presence of dup values are a bit arbitrary.
+ EXPECT_EQ("FOO1", unittest::TestEnumWithDupValue_Name(unittest::FOO1));
+ EXPECT_EQ("FOO1", unittest::TestEnumWithDupValue_Name(unittest::FOO2));
+
+ EXPECT_EQ("SPARSE_A", unittest::TestSparseEnum_Name(unittest::SPARSE_A));
+ EXPECT_EQ("SPARSE_B", unittest::TestSparseEnum_Name(unittest::SPARSE_B));
+ EXPECT_EQ("SPARSE_C", unittest::TestSparseEnum_Name(unittest::SPARSE_C));
+ EXPECT_EQ("SPARSE_D", unittest::TestSparseEnum_Name(unittest::SPARSE_D));
+ EXPECT_EQ("SPARSE_E", unittest::TestSparseEnum_Name(unittest::SPARSE_E));
+ EXPECT_EQ("SPARSE_F", unittest::TestSparseEnum_Name(unittest::SPARSE_F));
+ EXPECT_EQ("SPARSE_G", unittest::TestSparseEnum_Name(unittest::SPARSE_G));
+}
+
+TEST(GeneratedEnumTest, Parse) {
+ unittest::TestEnumWithDupValue dup_value = unittest::FOO1;
+ EXPECT_TRUE(unittest::TestEnumWithDupValue_Parse("FOO1", &dup_value));
+ EXPECT_EQ(unittest::FOO1, dup_value);
+ EXPECT_TRUE(unittest::TestEnumWithDupValue_Parse("FOO2", &dup_value));
+ EXPECT_EQ(unittest::FOO2, dup_value);
+ EXPECT_FALSE(unittest::TestEnumWithDupValue_Parse("FOO", &dup_value));
+}
+
+#endif // PROTOBUF_TEST_NO_DESCRIPTORS
+
// ===================================================================
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+
// Support code for testing services.
class GeneratedServiceTest : public testing::Test {
protected:
@@ -977,6 +1088,27 @@ TEST_F(GeneratedServiceTest, NotImplemented) {
EXPECT_TRUE(controller.called_);
}
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+
+// ===================================================================
+
+// This test must run last. It verifies that descriptors were or were not
+// initialized depending on whether PROTOBUF_TEST_NO_DESCRIPTORS was defined.
+// When this is defined, we skip all tests which are expected to trigger
+// descriptor initialization. This verifies that everything else still works
+// if descriptors are not initialized.
+TEST(DescriptorInitializationTest, Initialized) {
+#ifdef PROTOBUF_TEST_NO_DESCRIPTORS
+ bool should_have_descriptors = false;
+#else
+ bool should_have_descriptors = true;
+#endif
+
+ EXPECT_EQ(should_have_descriptors,
+ DescriptorPool::generated_pool()->InternalIsFileLoaded(
+ "google/protobuf/unittest.proto"));
+}
+
} // namespace cpp_unittest
} // namespace cpp