| Index: third_party/protobuf/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
|
| diff --git a/third_party/protobuf/src/google/protobuf/util/internal/protostream_objectwriter_test.cc b/third_party/protobuf/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
|
| index 9a0dcde1c4d1de29f19fb18948adc3d3c1c35fa9..a9b15e68a858443cbcbbc8ca6881cfbc8e73dc0f 100644
|
| --- a/third_party/protobuf/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
|
| +++ b/third_party/protobuf/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
|
| @@ -41,18 +41,20 @@
|
| #include <google/protobuf/dynamic_message.h>
|
| #include <google/protobuf/message.h>
|
| #include <google/protobuf/util/internal/mock_error_listener.h>
|
| +#include <google/protobuf/util/internal/testdata/anys.pb.h>
|
| #include <google/protobuf/util/internal/testdata/books.pb.h>
|
| #include <google/protobuf/util/internal/testdata/field_mask.pb.h>
|
| +#include <google/protobuf/util/internal/testdata/maps.pb.h>
|
| +#include <google/protobuf/util/internal/testdata/oneofs.pb.h>
|
| +#include <google/protobuf/util/internal/testdata/proto3.pb.h>
|
| +#include <google/protobuf/util/internal/testdata/struct.pb.h>
|
| +#include <google/protobuf/util/internal/testdata/timestamp_duration.pb.h>
|
| +#include <google/protobuf/util/internal/testdata/wrappers.pb.h>
|
| #include <google/protobuf/util/internal/type_info_test_helper.h>
|
| #include <google/protobuf/util/internal/constants.h>
|
| #include <google/protobuf/util/message_differencer.h>
|
| #include <google/protobuf/stubs/bytestream.h>
|
| #include <google/protobuf/stubs/strutil.h>
|
| -#include <google/protobuf/util/internal/testdata/anys.pb.h>
|
| -#include <google/protobuf/util/internal/testdata/maps.pb.h>
|
| -#include <google/protobuf/util/internal/testdata/oneofs.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>
|
|
|
|
|
| @@ -61,27 +63,28 @@ namespace protobuf {
|
| namespace util {
|
| namespace converter {
|
|
|
| +using google::protobuf::testing::AnyM;
|
| +using google::protobuf::testing::AnyOut;
|
| using google::protobuf::testing::Author;
|
| using google::protobuf::testing::Book;
|
| -using google::protobuf::testing::Book_Data;
|
| +using google::protobuf::testing::FieldMaskTest;
|
| +using google::protobuf::testing::Int32Wrapper;
|
| +using google::protobuf::testing::MapIn;
|
| using google::protobuf::testing::Primitive;
|
| +using google::protobuf::testing::Proto3Message;
|
| using google::protobuf::testing::Publisher;
|
| +using google::protobuf::testing::StructType;
|
| +using google::protobuf::testing::TimestampDuration;
|
| +using google::protobuf::testing::ValueWrapper;
|
| +using google::protobuf::testing::oneofs::OneOfsRequest;
|
| using google::protobuf::Descriptor;
|
| using google::protobuf::DescriptorPool;
|
| using google::protobuf::DynamicMessageFactory;
|
| using google::protobuf::FileDescriptorProto;
|
| using google::protobuf::Message;
|
| -using google::protobuf::io::ArrayInputStream;
|
| using strings::GrowingArrayByteSink;
|
| using ::testing::_;
|
| using ::testing::Args;
|
| -using google::protobuf::testing::anys::AnyM;
|
| -using google::protobuf::testing::anys::AnyOut;
|
| -using google::protobuf::testing::oneofs::OneOfsRequest;
|
| -using google::protobuf::testing::FieldMaskTest;
|
| -using google::protobuf::testing::maps::MapIn;
|
| -using google::protobuf::testing::structs::StructType;
|
| -using google::protobuf::testing::timestampduration::TimestampDuration;
|
|
|
|
|
| namespace {
|
| @@ -110,13 +113,13 @@ class BaseProtoStreamObjectWriterTest
|
| listener_(),
|
| output_(new GrowingArrayByteSink(1000)),
|
| ow_() {
|
| - vector<const Descriptor*> descriptors;
|
| + std::vector<const Descriptor*> descriptors;
|
| descriptors.push_back(descriptor);
|
| ResetTypeInfo(descriptors);
|
| }
|
|
|
| explicit BaseProtoStreamObjectWriterTest(
|
| - vector<const Descriptor*> descriptors)
|
| + std::vector<const Descriptor*> descriptors)
|
| : helper_(GetParam()),
|
| listener_(),
|
| output_(new GrowingArrayByteSink(1000)),
|
| @@ -124,7 +127,7 @@ class BaseProtoStreamObjectWriterTest
|
| ResetTypeInfo(descriptors);
|
| }
|
|
|
| - void ResetTypeInfo(vector<const Descriptor*> descriptors) {
|
| + void ResetTypeInfo(std::vector<const Descriptor*> descriptors) {
|
| GOOGLE_CHECK(!descriptors.empty()) << "Must have at least one descriptor!";
|
| helper_.ResetTypeInfo(descriptors);
|
| ow_.reset(helper_.NewProtoWriter(GetTypeUrl(descriptors[0]), output_.get(),
|
| @@ -132,7 +135,7 @@ class BaseProtoStreamObjectWriterTest
|
| }
|
|
|
| void ResetTypeInfo(const Descriptor* descriptor) {
|
| - vector<const Descriptor*> descriptors;
|
| + std::vector<const Descriptor*> descriptors;
|
| descriptors.push_back(descriptor);
|
| ResetTypeInfo(descriptors);
|
| }
|
| @@ -183,6 +186,10 @@ class ProtoStreamObjectWriterTest : public BaseProtoStreamObjectWriterTest {
|
| ProtoStreamObjectWriterTest()
|
| : BaseProtoStreamObjectWriterTest(Book::descriptor()) {}
|
|
|
| + void ResetProtoWriter() {
|
| + ResetTypeInfo(Book::descriptor());
|
| + }
|
| +
|
| virtual ~ProtoStreamObjectWriterTest() {}
|
| };
|
|
|
| @@ -264,6 +271,84 @@ TEST_P(ProtoStreamObjectWriterTest, CustomJsonName) {
|
| CheckOutput(book);
|
| }
|
|
|
| +TEST_P(ProtoStreamObjectWriterTest, IntEnumValuesAreAccepted) {
|
| + Book book;
|
| + book.set_title("Some Book");
|
| + book.set_type(google::protobuf::testing::Book_Type_KIDS);
|
| + Author* robert = book.mutable_author();
|
| + robert->set_name("robert");
|
| +
|
| + ow_->StartObject("")
|
| + ->RenderString("title", "Some Book")
|
| + ->RenderString("type", "2")
|
| + ->StartObject("author")
|
| + ->RenderString("name", "robert")
|
| + ->EndObject()
|
| + ->EndObject();
|
| + CheckOutput(book);
|
| +}
|
| +
|
| +TEST_P(ProtoStreamObjectWriterTest, EnumValuesWithoutUnderscoreAreAccepted) {
|
| + Book book;
|
| + book.set_title("Some Book");
|
| + book.set_type(google::protobuf::testing::Book_Type_ACTION_AND_ADVENTURE);
|
| + Author* robert = book.mutable_author();
|
| + robert->set_name("robert");
|
| +
|
| + options_.use_lower_camel_for_enums = true;
|
| + ResetProtoWriter();
|
| +
|
| + ow_->StartObject("")
|
| + ->RenderString("title", "Some Book")
|
| + ->RenderString("type", "ACTIONANDADVENTURE")
|
| + ->StartObject("author")
|
| + ->RenderString("name", "robert")
|
| + ->EndObject()
|
| + ->EndObject();
|
| + CheckOutput(book);
|
| +}
|
| +
|
| +TEST_P(ProtoStreamObjectWriterTest, EnumValuesInCamelCaseAreAccepted) {
|
| + Book book;
|
| + book.set_title("Some Book");
|
| + book.set_type(google::protobuf::testing::Book_Type_ACTION_AND_ADVENTURE);
|
| + Author* robert = book.mutable_author();
|
| + robert->set_name("robert");
|
| +
|
| + options_.use_lower_camel_for_enums = true;
|
| + ResetProtoWriter();
|
| +
|
| + ow_->StartObject("")
|
| + ->RenderString("title", "Some Book")
|
| + ->RenderString("type", "actionAndAdventure")
|
| + ->StartObject("author")
|
| + ->RenderString("name", "robert")
|
| + ->EndObject()
|
| + ->EndObject();
|
| + CheckOutput(book);
|
| +}
|
| +
|
| +TEST_P(ProtoStreamObjectWriterTest,
|
| + EnumValuesInCamelCaseWithNameNotUppercaseAreAccepted) {
|
| + Book book;
|
| + book.set_title("Some Book");
|
| + book.set_type(google::protobuf::testing::Book_Type_arts_and_photography);
|
| + Author* robert = book.mutable_author();
|
| + robert->set_name("robert");
|
| +
|
| + options_.use_lower_camel_for_enums = true;
|
| + ResetProtoWriter();
|
| +
|
| + ow_->StartObject("")
|
| + ->RenderString("title", "Some Book")
|
| + ->RenderString("type", "artsAndPhotography")
|
| + ->StartObject("author")
|
| + ->RenderString("name", "robert")
|
| + ->EndObject()
|
| + ->EndObject();
|
| + CheckOutput(book);
|
| +}
|
| +
|
| TEST_P(ProtoStreamObjectWriterTest, PrimitiveFromStringConversion) {
|
| Primitive full;
|
| full.set_fix32(101);
|
| @@ -709,6 +794,132 @@ TEST_P(ProtoStreamObjectWriterTest, UnknownListAtPublisher) {
|
| CheckOutput(expected);
|
| }
|
|
|
| +TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownFieldAtRoot) {
|
| + Book empty;
|
| +
|
| + options_.ignore_unknown_fields = true;
|
| + ResetProtoWriter();
|
| +
|
| + EXPECT_CALL(listener_, InvalidName(_, _, _)).Times(0);
|
| + ow_->StartObject("")->RenderString("unknown", "Nope!")->EndObject();
|
| + CheckOutput(empty, 0);
|
| +}
|
| +
|
| +TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownFieldAtAuthorFriend) {
|
| + Book expected;
|
| + Author* paul = expected.mutable_author();
|
| + paul->set_name("Paul");
|
| + Author* mark = paul->add_friend_();
|
| + mark->set_name("Mark");
|
| + Author* john = paul->add_friend_();
|
| + john->set_name("John");
|
| + Author* luke = paul->add_friend_();
|
| + luke->set_name("Luke");
|
| +
|
| + options_.ignore_unknown_fields = true;
|
| + ResetProtoWriter();
|
| +
|
| + EXPECT_CALL(listener_, InvalidName(_, _, _)).Times(0);
|
| + ow_->StartObject("")
|
| + ->StartObject("author")
|
| + ->RenderString("name", "Paul")
|
| + ->StartList("friend")
|
| + ->StartObject("")
|
| + ->RenderString("name", "Mark")
|
| + ->EndObject()
|
| + ->StartObject("")
|
| + ->RenderString("name", "John")
|
| + ->RenderString("address", "Patmos")
|
| + ->EndObject()
|
| + ->StartObject("")
|
| + ->RenderString("name", "Luke")
|
| + ->EndObject()
|
| + ->EndList()
|
| + ->EndObject()
|
| + ->EndObject();
|
| + CheckOutput(expected);
|
| +}
|
| +
|
| +TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownObjectAtRoot) {
|
| + Book empty;
|
| +
|
| + options_.ignore_unknown_fields = true;
|
| + ResetProtoWriter();
|
| +
|
| + EXPECT_CALL(listener_, InvalidName(_, StringPiece("unknown"),
|
| + StringPiece("Cannot find field.")))
|
| + .Times(0);
|
| + ow_->StartObject("")->StartObject("unknown")->EndObject()->EndObject();
|
| + CheckOutput(empty, 0);
|
| +}
|
| +
|
| +TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownObjectAtAuthor) {
|
| + Book expected;
|
| + Author* author = expected.mutable_author();
|
| + author->set_name("William");
|
| + author->add_pseudonym("Bill");
|
| +
|
| + options_.ignore_unknown_fields = true;
|
| + ResetProtoWriter();
|
| +
|
| + EXPECT_CALL(listener_, InvalidName(_, _, _)).Times(0);
|
| + ow_->StartObject("")
|
| + ->StartObject("author")
|
| + ->RenderString("name", "William")
|
| + ->StartObject("wife")
|
| + ->RenderString("name", "Hilary")
|
| + ->EndObject()
|
| + ->RenderString("pseudonym", "Bill")
|
| + ->EndObject()
|
| + ->EndObject();
|
| + CheckOutput(expected);
|
| +}
|
| +
|
| +TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownListAtRoot) {
|
| + Book empty;
|
| +
|
| + options_.ignore_unknown_fields = true;
|
| + ResetProtoWriter();
|
| +
|
| + EXPECT_CALL(listener_, InvalidName(_, _, _)).Times(0);
|
| + ow_->StartObject("")->StartList("unknown")->EndList()->EndObject();
|
| + CheckOutput(empty, 0);
|
| +}
|
| +
|
| +TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownListAtPublisher) {
|
| + Book expected;
|
| + expected.set_title("Brainwashing");
|
| + Publisher* publisher = expected.mutable_publisher();
|
| + publisher->set_name("propaganda");
|
| +
|
| + options_.ignore_unknown_fields = true;
|
| + ResetProtoWriter();
|
| +
|
| + EXPECT_CALL(listener_, InvalidName(_, _, _)).Times(0);
|
| + ow_->StartObject("")
|
| + ->StartObject("publisher")
|
| + ->RenderString("name", "propaganda")
|
| + ->StartList("alliance")
|
| + ->EndList()
|
| + ->EndObject()
|
| + ->RenderString("title", "Brainwashing")
|
| + ->EndObject();
|
| + CheckOutput(expected);
|
| +}
|
| +
|
| +TEST_P(ProtoStreamObjectWriterTest, AcceptUnknownEnumValue) {
|
| + ResetTypeInfo(Proto3Message::descriptor());
|
| +
|
| + Proto3Message expected;
|
| + expected.set_enum_value(static_cast<Proto3Message::NestedEnum>(12345));
|
| +
|
| + EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
|
| + ow_->StartObject("")
|
| + ->RenderInt32("enumValue", 12345)
|
| + ->EndObject();
|
| + CheckOutput(expected);
|
| +}
|
| +
|
| TEST_P(ProtoStreamObjectWriterTest, MissingRequiredField) {
|
| Book expected;
|
| expected.set_title("My Title");
|
| @@ -867,7 +1078,7 @@ class ProtoStreamObjectWriterTimestampDurationTest
|
| : public BaseProtoStreamObjectWriterTest {
|
| protected:
|
| ProtoStreamObjectWriterTimestampDurationTest() {
|
| - vector<const Descriptor*> descriptors;
|
| + std::vector<const Descriptor*> descriptors;
|
| descriptors.push_back(TimestampDuration::descriptor());
|
| descriptors.push_back(google::protobuf::Timestamp::descriptor());
|
| descriptors.push_back(google::protobuf::Duration::descriptor());
|
| @@ -1221,9 +1432,9 @@ TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
|
| InvalidValue(
|
| _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
|
| StringPiece(
|
| - "Field 'ts', Invalid data type for timestamp, value is null")))
|
| + "Field 'ts', Invalid data type for timestamp, value is 1")))
|
| .With(Args<0>(HasObjectLocation("ts")));
|
| - ow_->StartObject("")->RenderNull("ts")->EndObject();
|
| + ow_->StartObject("")->RenderInt32("ts", 1)->EndObject();
|
| CheckOutput(timestamp);
|
| }
|
|
|
| @@ -1235,8 +1446,22 @@ TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
|
| InvalidValue(
|
| _, StringPiece("type.googleapis.com/google.protobuf.Duration"),
|
| StringPiece(
|
| - "Field 'dur', Invalid data type for duration, value is null")))
|
| + "Field 'dur', Invalid data type for duration, value is 1")))
|
| .With(Args<0>(HasObjectLocation("dur")));
|
| + ow_->StartObject("")->RenderInt32("dur", 1)->EndObject();
|
| + CheckOutput(duration);
|
| +}
|
| +
|
| +TEST_P(ProtoStreamObjectWriterTimestampDurationTest, TimestampAcceptsNull) {
|
| + TimestampDuration timestamp;
|
| + EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
|
| + ow_->StartObject("")->RenderNull("ts")->EndObject();
|
| + CheckOutput(timestamp);
|
| +}
|
| +
|
| +TEST_P(ProtoStreamObjectWriterTimestampDurationTest, DurationAcceptsNull) {
|
| + TimestampDuration duration;
|
| + EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
|
| ow_->StartObject("")->RenderNull("dur")->EndObject();
|
| CheckOutput(duration);
|
| }
|
| @@ -1248,7 +1473,7 @@ class ProtoStreamObjectWriterStructTest
|
|
|
| // Resets ProtoWriter with current set of options and other state.
|
| void ResetProtoWriter() {
|
| - vector<const Descriptor*> descriptors;
|
| + std::vector<const Descriptor*> descriptors;
|
| descriptors.push_back(StructType::descriptor());
|
| descriptors.push_back(google::protobuf::Struct::descriptor());
|
| ResetTypeInfo(descriptors);
|
| @@ -1298,6 +1523,28 @@ TEST_P(ProtoStreamObjectWriterStructTest, StructInvalidInputFailure) {
|
| CheckOutput(struct_type);
|
| }
|
|
|
| +TEST_P(ProtoStreamObjectWriterStructTest, StructAcceptsNull) {
|
| + StructType struct_type;
|
| + EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
|
| +
|
| + ow_->StartObject("")->RenderNull("object")->EndObject();
|
| + CheckOutput(struct_type);
|
| +}
|
| +
|
| +TEST_P(ProtoStreamObjectWriterStructTest, StructValuePreservesNull) {
|
| + StructType struct_type;
|
| + (*struct_type.mutable_object()->mutable_fields())["key"].set_null_value(
|
| + google::protobuf::NULL_VALUE);
|
| + EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
|
| +
|
| + ow_->StartObject("")
|
| + ->StartObject("object")
|
| + ->RenderNull("key")
|
| + ->EndObject()
|
| + ->EndObject();
|
| + CheckOutput(struct_type);
|
| +}
|
| +
|
| TEST_P(ProtoStreamObjectWriterStructTest, SimpleRepeatedStructMapKeyTest) {
|
| EXPECT_CALL(
|
| listener_,
|
| @@ -1365,6 +1612,15 @@ TEST_P(ProtoStreamObjectWriterStructTest, OptionStructIntAsStringsTest) {
|
| CheckOutput(struct_type);
|
| }
|
|
|
| +TEST_P(ProtoStreamObjectWriterStructTest, ValuePreservesNull) {
|
| + ValueWrapper value;
|
| + value.mutable_value()->set_null_value(google::protobuf::NULL_VALUE);
|
| +
|
| + EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
|
| + ow_->StartObject("")->RenderNull("value")->EndObject();
|
| + CheckOutput(value);
|
| +}
|
| +
|
| class ProtoStreamObjectWriterMapTest : public BaseProtoStreamObjectWriterTest {
|
| protected:
|
| ProtoStreamObjectWriterMapTest()
|
| @@ -1408,13 +1664,16 @@ TEST_P(ProtoStreamObjectWriterMapTest, RepeatedMapKeyTest) {
|
| class ProtoStreamObjectWriterAnyTest : public BaseProtoStreamObjectWriterTest {
|
| protected:
|
| ProtoStreamObjectWriterAnyTest() {
|
| - vector<const Descriptor*> descriptors;
|
| + std::vector<const Descriptor*> descriptors;
|
| descriptors.push_back(AnyOut::descriptor());
|
| + descriptors.push_back(Book::descriptor());
|
| + descriptors.push_back(google::protobuf::Any::descriptor());
|
| descriptors.push_back(google::protobuf::DoubleValue::descriptor());
|
| + descriptors.push_back(google::protobuf::FieldMask::descriptor());
|
| + descriptors.push_back(google::protobuf::Int32Value::descriptor());
|
| + descriptors.push_back(google::protobuf::Struct::descriptor());
|
| descriptors.push_back(google::protobuf::Timestamp::descriptor());
|
| - descriptors.push_back(google::protobuf::Any::descriptor());
|
| descriptors.push_back(google::protobuf::Value::descriptor());
|
| - descriptors.push_back(google::protobuf::Struct::descriptor());
|
| ResetTypeInfo(descriptors);
|
| }
|
| };
|
| @@ -1447,8 +1706,7 @@ TEST_P(ProtoStreamObjectWriterAnyTest, RecursiveAny) {
|
| any->set_type_url("type.googleapis.com/google.protobuf.Any");
|
|
|
| ::google::protobuf::Any nested_any;
|
| - nested_any.set_type_url(
|
| - "type.googleapis.com/google.protobuf.testing.anys.AnyM");
|
| + nested_any.set_type_url("type.googleapis.com/google.protobuf.testing.AnyM");
|
|
|
| AnyM m;
|
| m.set_foo("foovalue");
|
| @@ -1461,11 +1719,12 @@ TEST_P(ProtoStreamObjectWriterAnyTest, RecursiveAny) {
|
| ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
|
| ->StartObject("value")
|
| ->RenderString("@type",
|
| - "type.googleapis.com/google.protobuf.testing.anys.AnyM")
|
| + "type.googleapis.com/google.protobuf.testing.AnyM")
|
| ->RenderString("foo", "foovalue")
|
| ->EndObject()
|
| ->EndObject()
|
| ->EndObject();
|
| + CheckOutput(out, 107);
|
| }
|
|
|
| TEST_P(ProtoStreamObjectWriterAnyTest, DoubleRecursiveAny) {
|
| @@ -1478,7 +1737,7 @@ TEST_P(ProtoStreamObjectWriterAnyTest, DoubleRecursiveAny) {
|
|
|
| ::google::protobuf::Any second_nested_any;
|
| second_nested_any.set_type_url(
|
| - "type.googleapis.com/google.protobuf.testing.anys.AnyM");
|
| + "type.googleapis.com/google.protobuf.testing.AnyM");
|
|
|
| AnyM m;
|
| m.set_foo("foovalue");
|
| @@ -1494,18 +1753,110 @@ TEST_P(ProtoStreamObjectWriterAnyTest, DoubleRecursiveAny) {
|
| ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
|
| ->StartObject("value")
|
| ->RenderString("@type",
|
| - "type.googleapis.com/google.protobuf.testing.anys.AnyM")
|
| + "type.googleapis.com/google.protobuf.testing.AnyM")
|
| ->RenderString("foo", "foovalue")
|
| ->EndObject()
|
| ->EndObject()
|
| ->EndObject()
|
| ->EndObject();
|
| + CheckOutput(out, 151);
|
| +}
|
| +
|
| +TEST_P(ProtoStreamObjectWriterAnyTest, TypeUrlAtEnd) {
|
| + Book book;
|
| + book.set_title("C++");
|
| + book.set_length(1234);
|
| + book.set_content("Hello World!");
|
| +
|
| + ::google::protobuf::Any any;
|
| + any.PackFrom(book);
|
| +
|
| + ::google::protobuf::Any outer_any;
|
| + outer_any.PackFrom(any);
|
| +
|
| + AnyOut out;
|
| + out.mutable_any()->PackFrom(outer_any);
|
| +
|
| + // Put the @type field at the end of each Any message. Parsers should
|
| + // be able to accept that.
|
| + ow_->StartObject("")
|
| + ->StartObject("any")
|
| + ->StartObject("value")
|
| + ->StartObject("value")
|
| + ->RenderString("title", "C++")
|
| + ->RenderInt32("length", 1234)
|
| + ->RenderBytes("content", "Hello World!")
|
| + ->RenderString("@type",
|
| + "type.googleapis.com/google.protobuf.testing.Book")
|
| + ->EndObject()
|
| + ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
|
| + ->EndObject()
|
| + ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
|
| + ->EndObject()
|
| + ->EndObject();
|
| + CheckOutput(out);
|
| +}
|
| +
|
| +// Same as TypeUrlAtEnd, but use temporary string values to make sure we don't
|
| +// mistakenly store StringPiece objects pointing to invalid memory.
|
| +TEST_P(ProtoStreamObjectWriterAnyTest, TypeUrlAtEndWithTemporaryStrings) {
|
| + Book book;
|
| + book.set_title("C++");
|
| + book.set_length(1234);
|
| + book.set_content("Hello World!");
|
| +
|
| + ::google::protobuf::Any any;
|
| + any.PackFrom(book);
|
| +
|
| + ::google::protobuf::Any outer_any;
|
| + outer_any.PackFrom(any);
|
| +
|
| + AnyOut out;
|
| + out.mutable_any()->PackFrom(outer_any);
|
| +
|
| + string name, value;
|
| + // Put the @type field at the end of each Any message. Parsers should
|
| + // be able to accept that.
|
| + ow_->StartObject("")->StartObject("any");
|
| + {
|
| + ow_->StartObject("value");
|
| + {
|
| + ow_->StartObject("value");
|
| + {
|
| + name = "title";
|
| + value = "C++";
|
| + ow_->RenderString(name, value);
|
| + name = "length";
|
| + ow_->RenderInt32(name, 1234);
|
| + name = "content";
|
| + value = "Hello World!";
|
| + ow_->RenderBytes(name, value);
|
| + name = "@type";
|
| + value = "type.googleapis.com/google.protobuf.testing.Book";
|
| + ow_->RenderString(name, value);
|
| + }
|
| + ow_->EndObject();
|
| +
|
| + name = "@type";
|
| + value = "type.googleapis.com/google.protobuf.Any";
|
| + ow_->RenderString(name, value);
|
| + }
|
| + ow_->EndObject();
|
| +
|
| + name = "@type";
|
| + value = "type.googleapis.com/google.protobuf.Any";
|
| + ow_->RenderString(name, value);
|
| + }
|
| + ow_->EndObject()->EndObject();
|
| + CheckOutput(out);
|
| }
|
|
|
| TEST_P(ProtoStreamObjectWriterAnyTest, EmptyAnyFromEmptyObject) {
|
| AnyOut out;
|
| out.mutable_any();
|
|
|
| + EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
|
| +
|
| ow_->StartObject("")->StartObject("any")->EndObject()->EndObject();
|
|
|
| CheckOutput(out, 2);
|
| @@ -1514,11 +1865,10 @@ TEST_P(ProtoStreamObjectWriterAnyTest, EmptyAnyFromEmptyObject) {
|
| TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithoutTypeUrlFails1) {
|
| AnyOut any;
|
|
|
| - EXPECT_CALL(
|
| - listener_,
|
| - InvalidValue(_, StringPiece("Any"),
|
| - StringPiece("Missing or invalid @type for any field in "
|
| - "google.protobuf.testing.anys.AnyOut")));
|
| + EXPECT_CALL(listener_,
|
| + InvalidValue(_, StringPiece("Any"),
|
| + StringPiece("Missing @type for any field in "
|
| + "google.protobuf.testing.AnyOut")));
|
|
|
| ow_->StartObject("")
|
| ->StartObject("any")
|
| @@ -1532,11 +1882,10 @@ TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithoutTypeUrlFails1) {
|
| TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithoutTypeUrlFails2) {
|
| AnyOut any;
|
|
|
| - EXPECT_CALL(
|
| - listener_,
|
| - InvalidValue(_, StringPiece("Any"),
|
| - StringPiece("Missing or invalid @type for any field in "
|
| - "google.protobuf.testing.anys.AnyOut")));
|
| + EXPECT_CALL(listener_,
|
| + InvalidValue(_, StringPiece("Any"),
|
| + StringPiece("Missing @type for any field in "
|
| + "google.protobuf.testing.AnyOut")));
|
|
|
| ow_->StartObject("")
|
| ->StartObject("any")
|
| @@ -1550,11 +1899,10 @@ TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithoutTypeUrlFails2) {
|
| TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithoutTypeUrlFails3) {
|
| AnyOut any;
|
|
|
| - EXPECT_CALL(
|
| - listener_,
|
| - InvalidValue(_, StringPiece("Any"),
|
| - StringPiece("Missing or invalid @type for any field in "
|
| - "google.protobuf.testing.anys.AnyOut")));
|
| + EXPECT_CALL(listener_,
|
| + InvalidValue(_, StringPiece("Any"),
|
| + StringPiece("Missing @type for any field in "
|
| + "google.protobuf.testing.AnyOut")));
|
|
|
| ow_->StartObject("")
|
| ->StartObject("any")
|
| @@ -1599,9 +1947,21 @@ TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithUnknownTypeFails) {
|
| CheckOutput(any);
|
| }
|
|
|
| -TEST_P(ProtoStreamObjectWriterAnyTest, AnyNullInputFails) {
|
| +TEST_P(ProtoStreamObjectWriterAnyTest, AnyIncorrectInputTypeFails) {
|
| + AnyOut any;
|
| +
|
| + EXPECT_CALL(
|
| + listener_,
|
| + InvalidValue(_, StringPiece("type.googleapis.com/google.protobuf.Any"),
|
| + StringPiece("1")));
|
| + ow_->StartObject("")->RenderInt32("any", 1)->EndObject();
|
| + CheckOutput(any);
|
| +}
|
| +
|
| +TEST_P(ProtoStreamObjectWriterAnyTest, AnyAcceptsNull) {
|
| AnyOut any;
|
|
|
| + EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
|
| ow_->StartObject("")->RenderNull("any")->EndObject();
|
| CheckOutput(any);
|
| }
|
| @@ -1839,11 +2199,116 @@ TEST_P(ProtoStreamObjectWriterAnyTest, AnyWellKnownTypesExpectObjectForAny) {
|
| CheckOutput(any);
|
| }
|
|
|
| +// {
|
| +// "any": {
|
| +// "@type": "type.googleapis.com/google.protobuf.Any",
|
| +// "value": null
|
| +// }
|
| +// }
|
| +TEST_P(ProtoStreamObjectWriterAnyTest, AnyInAnyAcceptsNull) {
|
| + AnyOut out;
|
| + google::protobuf::Any empty;
|
| + out.mutable_any()->PackFrom(empty);
|
| +
|
| + EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
|
| + ow_->StartObject("")
|
| + ->StartObject("any")
|
| + ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
|
| + ->RenderNull("value")
|
| + ->EndObject()
|
| + ->EndObject();
|
| + CheckOutput(out);
|
| +}
|
| +
|
| +// {
|
| +// "any": {
|
| +// "@type": "type.googleapis.com/google.protobuf.Timestamp",
|
| +// "value": null
|
| +// }
|
| +// }
|
| +TEST_P(ProtoStreamObjectWriterAnyTest, TimestampInAnyAcceptsNull) {
|
| + AnyOut out;
|
| + google::protobuf::Timestamp empty;
|
| + out.mutable_any()->PackFrom(empty);
|
| +
|
| + EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
|
| + ow_->StartObject("")
|
| + ->StartObject("any")
|
| + ->RenderString("@type", "type.googleapis.com/google.protobuf.Timestamp")
|
| + ->RenderNull("value")
|
| + ->EndObject()
|
| + ->EndObject();
|
| + CheckOutput(out);
|
| +}
|
| +
|
| +// {
|
| +// "any": {
|
| +// "@type": "type.googleapis.com/google.protobuf.Duration",
|
| +// "value": null
|
| +// }
|
| +// }
|
| +TEST_P(ProtoStreamObjectWriterAnyTest, DurationInAnyAcceptsNull) {
|
| + AnyOut out;
|
| + google::protobuf::Duration empty;
|
| + out.mutable_any()->PackFrom(empty);
|
| +
|
| + EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
|
| + ow_->StartObject("")
|
| + ->StartObject("any")
|
| + ->RenderString("@type", "type.googleapis.com/google.protobuf.Duration")
|
| + ->RenderNull("value")
|
| + ->EndObject()
|
| + ->EndObject();
|
| + CheckOutput(out);
|
| +}
|
| +
|
| +// {
|
| +// "any": {
|
| +// "@type": "type.googleapis.com/google.protobuf.FieldMask",
|
| +// "value": null
|
| +// }
|
| +// }
|
| +TEST_P(ProtoStreamObjectWriterAnyTest, FieldMaskInAnyAcceptsNull) {
|
| + AnyOut out;
|
| + google::protobuf::FieldMask empty;
|
| + out.mutable_any()->PackFrom(empty);
|
| +
|
| + EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
|
| + ow_->StartObject("")
|
| + ->StartObject("any")
|
| + ->RenderString("@type", "type.googleapis.com/google.protobuf.FieldMask")
|
| + ->RenderNull("value")
|
| + ->EndObject()
|
| + ->EndObject();
|
| + CheckOutput(out);
|
| +}
|
| +
|
| +// {
|
| +// "any": {
|
| +// "@type": "type.googleapis.com/google.protobuf.Int32Value",
|
| +// "value": null
|
| +// }
|
| +// }
|
| +TEST_P(ProtoStreamObjectWriterAnyTest, WrapperInAnyAcceptsNull) {
|
| + AnyOut out;
|
| + google::protobuf::Int32Value empty;
|
| + out.mutable_any()->PackFrom(empty);
|
| +
|
| + EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
|
| + ow_->StartObject("")
|
| + ->StartObject("any")
|
| + ->RenderString("@type", "type.googleapis.com/google.protobuf.Int32Value")
|
| + ->RenderNull("value")
|
| + ->EndObject()
|
| + ->EndObject();
|
| + CheckOutput(out);
|
| +}
|
| +
|
| class ProtoStreamObjectWriterFieldMaskTest
|
| : public BaseProtoStreamObjectWriterTest {
|
| protected:
|
| ProtoStreamObjectWriterFieldMaskTest() {
|
| - vector<const Descriptor*> descriptors;
|
| + std::vector<const Descriptor*> descriptors;
|
| descriptors.push_back(FieldMaskTest::descriptor());
|
| descriptors.push_back(google::protobuf::FieldMask::descriptor());
|
| ResetTypeInfo(descriptors);
|
| @@ -2084,11 +2549,41 @@ TEST_P(ProtoStreamObjectWriterFieldMaskTest, MapKeyCanContainAnyChars) {
|
| CheckOutput(expected);
|
| }
|
|
|
| +TEST_P(ProtoStreamObjectWriterFieldMaskTest, FieldMaskAcceptsNull) {
|
| + FieldMaskTest expected;
|
| + EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
|
| + ow_->StartObject("")->RenderNull("single_mask")->EndObject();
|
| + CheckOutput(expected);
|
| +}
|
| +
|
| +class ProtoStreamObjectWriterWrappersTest
|
| + : public BaseProtoStreamObjectWriterTest {
|
| + protected:
|
| + ProtoStreamObjectWriterWrappersTest() {
|
| + std::vector<const Descriptor*> descriptors;
|
| + descriptors.push_back(Int32Wrapper::descriptor());
|
| + descriptors.push_back(google::protobuf::Int32Value::descriptor());
|
| + ResetTypeInfo(descriptors);
|
| + }
|
| +};
|
| +
|
| +INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
|
| + ProtoStreamObjectWriterWrappersTest,
|
| + ::testing::Values(
|
| + testing::USE_TYPE_RESOLVER));
|
| +
|
| +TEST_P(ProtoStreamObjectWriterWrappersTest, WrapperAcceptsNull) {
|
| + Int32Wrapper wrapper;
|
| + EXPECT_CALL(listener_, InvalidName(_, _, _)).Times(0);
|
| + ow_->StartObject("")->RenderNull("int32")->EndObject();
|
| + CheckOutput(wrapper);
|
| +}
|
| +
|
| class ProtoStreamObjectWriterOneOfsTest
|
| : public BaseProtoStreamObjectWriterTest {
|
| protected:
|
| ProtoStreamObjectWriterOneOfsTest() {
|
| - vector<const Descriptor*> descriptors;
|
| + std::vector<const Descriptor*> descriptors;
|
| descriptors.push_back(OneOfsRequest::descriptor());
|
| descriptors.push_back(google::protobuf::Struct::descriptor());
|
| ResetTypeInfo(descriptors);
|
| @@ -2251,7 +2746,6 @@ TEST_P(ProtoStreamObjectWriterOneOfsTest,
|
| StringPiece("oneof field 'data' is already set. "
|
| "Cannot set 'intData'")));
|
|
|
| - using google::protobuf::testing::oneofs::OneOfsRequest;
|
| // JSON:
|
| // { "anyData":
|
| // { "@type":
|
|
|