| Index: third_party/protobuf/src/google/protobuf/util/internal/protostream_objectsource_test.cc
|
| diff --git a/third_party/protobuf/src/google/protobuf/util/internal/protostream_objectsource_test.cc b/third_party/protobuf/src/google/protobuf/util/internal/protostream_objectsource_test.cc
|
| index 561f67634e78f181751f859b17b157cc5283dc87..3f6fdf973f6f391d7923285f4fb84479d160e002 100644
|
| --- a/third_party/protobuf/src/google/protobuf/util/internal/protostream_objectsource_test.cc
|
| +++ b/third_party/protobuf/src/google/protobuf/util/internal/protostream_objectsource_test.cc
|
| @@ -50,6 +50,7 @@
|
| #include <google/protobuf/util/internal/testdata/anys.pb.h>
|
| #include <google/protobuf/util/internal/testdata/maps.pb.h>
|
| #include <google/protobuf/util/internal/testdata/struct.pb.h>
|
| +#include <google/protobuf/util/internal/testdata/timestamp_duration.pb.h>
|
| #include <gtest/gtest.h>
|
|
|
|
|
| @@ -69,12 +70,15 @@ using google::protobuf::testing::Author;
|
| using google::protobuf::testing::BadAuthor;
|
| using google::protobuf::testing::BadNestedBook;
|
| using google::protobuf::testing::Book;
|
| +using google::protobuf::testing::Cyclic;
|
| using google::protobuf::testing::Book_Label;
|
| using google::protobuf::testing::NestedBook;
|
| using google::protobuf::testing::PackedPrimitive;
|
| using google::protobuf::testing::Primitive;
|
| using google::protobuf::testing::more_author;
|
| using google::protobuf::testing::maps::MapOut;
|
| +using google::protobuf::testing::maps::MapOutWireFormat;
|
| +using google::protobuf::testing::timestampduration::TimestampDuration;
|
| using google::protobuf::testing::anys::AnyOut;
|
| using google::protobuf::testing::anys::AnyM;
|
| using google::protobuf::testing::FieldMaskTest;
|
| @@ -92,7 +96,11 @@ string GetTypeUrl(const Descriptor* descriptor) {
|
| class ProtostreamObjectSourceTest
|
| : public ::testing::TestWithParam<testing::TypeInfoSource> {
|
| protected:
|
| - ProtostreamObjectSourceTest() : helper_(GetParam()), mock_(), ow_(&mock_) {
|
| + ProtostreamObjectSourceTest()
|
| + : helper_(GetParam()),
|
| + mock_(),
|
| + ow_(&mock_),
|
| + use_lower_camel_for_enums_(false) {
|
| helper_.ResetTypeInfo(Book::descriptor());
|
| }
|
|
|
| @@ -112,6 +120,8 @@ class ProtostreamObjectSourceTest
|
|
|
| google::protobuf::scoped_ptr<ProtoStreamObjectSource> os(
|
| helper_.NewProtoSource(&in_stream, GetTypeUrl(descriptor)));
|
| + if (use_lower_camel_for_enums_) os->set_use_lower_camel_for_enums(true);
|
| + os->set_max_recursion_depth(64);
|
| return os->WriteTo(&mock_);
|
| }
|
|
|
| @@ -256,10 +266,13 @@ class ProtostreamObjectSourceTest
|
| return primitive;
|
| }
|
|
|
| + void UseLowerCamelForEnums() { use_lower_camel_for_enums_ = true; }
|
| +
|
| testing::TypeInfoTestHelper helper_;
|
|
|
| ::testing::NiceMock<MockObjectWriter> mock_;
|
| ExpectingObjectWriter ow_;
|
| + bool use_lower_camel_for_enums_;
|
| };
|
|
|
| INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
|
| @@ -461,6 +474,52 @@ TEST_P(ProtostreamObjectSourceTest,
|
| DoTest(book, Book::descriptor());
|
| }
|
|
|
| +TEST_P(ProtostreamObjectSourceTest, LowerCamelEnumOutputTest) {
|
| + Book book;
|
| + book.set_type(Book::ACTION_AND_ADVENTURE);
|
| +
|
| + UseLowerCamelForEnums();
|
| +
|
| + ow_.StartObject("")->RenderString("type", "actionAndAdventure")->EndObject();
|
| + DoTest(book, Book::descriptor());
|
| +}
|
| +
|
| +TEST_P(ProtostreamObjectSourceTest, EnumCaseIsUnchangedByDefault) {
|
| + Book book;
|
| + book.set_type(Book::ACTION_AND_ADVENTURE);
|
| + ow_.StartObject("")
|
| + ->RenderString("type", "ACTION_AND_ADVENTURE")
|
| + ->EndObject();
|
| + DoTest(book, Book::descriptor());
|
| +}
|
| +
|
| +TEST_P(ProtostreamObjectSourceTest, CyclicMessageDepthTest) {
|
| + Cyclic cyclic;
|
| + cyclic.set_m_int(123);
|
| +
|
| + Book* book = cyclic.mutable_m_book();
|
| + book->set_title("book title");
|
| + Cyclic* current = cyclic.mutable_m_cyclic();
|
| + Author* current_author = cyclic.add_m_author();
|
| + for (int i = 0; i < 63; ++i) {
|
| + Author* next = current_author->add_friend_();
|
| + next->set_id(i);
|
| + next->set_name(StrCat("author_name_", i));
|
| + next->set_alive(true);
|
| + current_author = next;
|
| + }
|
| +
|
| + // Recursive message with depth (65) > max (max is 64).
|
| + for (int i = 0; i < 64; ++i) {
|
| + Cyclic* next = current->mutable_m_cyclic();
|
| + next->set_m_str(StrCat("count_", i));
|
| + current = next;
|
| + }
|
| +
|
| + Status status = ExecuteTest(cyclic, Cyclic::descriptor());
|
| + EXPECT_EQ(util::error::INVALID_ARGUMENT, status.error_code());
|
| +}
|
| +
|
| class ProtostreamObjectSourceMapsTest : public ProtostreamObjectSourceTest {
|
| protected:
|
| ProtostreamObjectSourceMapsTest() {
|
| @@ -541,6 +600,67 @@ TEST_P(ProtostreamObjectSourceMapsTest, MapsTest) {
|
| DoTest(out, MapOut::descriptor());
|
| }
|
|
|
| +TEST_P(ProtostreamObjectSourceMapsTest, MissingKeysTest) {
|
| + // MapOutWireFormat has the same wire representation with MapOut but uses
|
| + // repeated message fields to represent map fields so we can intentionally
|
| + // leave out the key field or the value field of a map entry.
|
| + MapOutWireFormat out;
|
| + // Create some map entries without keys. They will be rendered with the
|
| + // default values ("" for strings, "0" for integers, etc.).
|
| + // {
|
| + // "map1": {
|
| + // "": {
|
| + // "foo": "foovalue"
|
| + // }
|
| + // },
|
| + // "map2": {
|
| + // "": {
|
| + // "map1": {
|
| + // "nested_key1": {
|
| + // "foo": "nested_foo"
|
| + // }
|
| + // }
|
| + // }
|
| + // },
|
| + // "map3": {
|
| + // "0": "one one one"
|
| + // },
|
| + // "map4": {
|
| + // "false": "bool"
|
| + // }
|
| + // }
|
| + out.add_map1()->mutable_value()->set_foo("foovalue");
|
| + MapOut* nested = out.add_map2()->mutable_value();
|
| + (*nested->mutable_map1())["nested_key1"].set_foo("nested_foo");
|
| + out.add_map3()->set_value("one one one");
|
| + out.add_map4()->set_value("bool");
|
| +
|
| + ow_.StartObject("")
|
| + ->StartObject("map1")
|
| + ->StartObject("")
|
| + ->RenderString("foo", "foovalue")
|
| + ->EndObject()
|
| + ->EndObject()
|
| + ->StartObject("map2")
|
| + ->StartObject("")
|
| + ->StartObject("map1")
|
| + ->StartObject("nested_key1")
|
| + ->RenderString("foo", "nested_foo")
|
| + ->EndObject()
|
| + ->EndObject()
|
| + ->EndObject()
|
| + ->EndObject()
|
| + ->StartObject("map3")
|
| + ->RenderString("0", "one one one")
|
| + ->EndObject()
|
| + ->StartObject("map4")
|
| + ->RenderString("false", "bool")
|
| + ->EndObject()
|
| + ->EndObject();
|
| +
|
| + DoTest(out, MapOut::descriptor());
|
| +}
|
| +
|
| class ProtostreamObjectSourceAnysTest : public ProtostreamObjectSourceTest {
|
| protected:
|
| ProtostreamObjectSourceAnysTest() {
|
| @@ -824,6 +944,63 @@ TEST_P(ProtostreamObjectSourceFieldMaskTest, FieldMaskRenderSuccess) {
|
| DoTest(out, FieldMaskTest::descriptor());
|
| }
|
|
|
| +class ProtostreamObjectSourceTimestampTest
|
| + : public ProtostreamObjectSourceTest {
|
| + protected:
|
| + ProtostreamObjectSourceTimestampTest() {
|
| + helper_.ResetTypeInfo(TimestampDuration::descriptor());
|
| + }
|
| +};
|
| +
|
| +INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
|
| + ProtostreamObjectSourceTimestampTest,
|
| + ::testing::Values(
|
| + testing::USE_TYPE_RESOLVER));
|
| +
|
| +TEST_P(ProtostreamObjectSourceTimestampTest, InvalidTimestampBelowMinTest) {
|
| + TimestampDuration out;
|
| + google::protobuf::Timestamp* ts = out.mutable_ts();
|
| + // Min allowed seconds - 1
|
| + ts->set_seconds(kTimestampMinSeconds - 1);
|
| + ow_.StartObject("");
|
| +
|
| + Status status = ExecuteTest(out, TimestampDuration::descriptor());
|
| + EXPECT_EQ(util::error::INTERNAL, status.error_code());
|
| +}
|
| +
|
| +TEST_P(ProtostreamObjectSourceTimestampTest, InvalidTimestampAboveMaxTest) {
|
| + TimestampDuration out;
|
| + google::protobuf::Timestamp* ts = out.mutable_ts();
|
| + // Max allowed seconds + 1
|
| + ts->set_seconds(kTimestampMaxSeconds + 1);
|
| + ow_.StartObject("");
|
| +
|
| + Status status = ExecuteTest(out, TimestampDuration::descriptor());
|
| + EXPECT_EQ(util::error::INTERNAL, status.error_code());
|
| +}
|
| +
|
| +TEST_P(ProtostreamObjectSourceTimestampTest, InvalidDurationBelowMinTest) {
|
| + TimestampDuration out;
|
| + google::protobuf::Duration* dur = out.mutable_dur();
|
| + // Min allowed seconds - 1
|
| + dur->set_seconds(kDurationMinSeconds - 1);
|
| + ow_.StartObject("");
|
| +
|
| + Status status = ExecuteTest(out, TimestampDuration::descriptor());
|
| + EXPECT_EQ(util::error::INTERNAL, status.error_code());
|
| +}
|
| +
|
| +TEST_P(ProtostreamObjectSourceTimestampTest, InvalidDurationAboveMaxTest) {
|
| + TimestampDuration out;
|
| + google::protobuf::Duration* dur = out.mutable_dur();
|
| + // Min allowed seconds + 1
|
| + dur->set_seconds(kDurationMaxSeconds + 1);
|
| + ow_.StartObject("");
|
| +
|
| + Status status = ExecuteTest(out, TimestampDuration::descriptor());
|
| + EXPECT_EQ(util::error::INTERNAL, status.error_code());
|
| +}
|
| +
|
| } // namespace converter
|
| } // namespace util
|
| } // namespace protobuf
|
|
|