| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087 |
- // Protocol Buffers - Google's data interchange format
- // Copyright 2008 Google Inc. All rights reserved.
- // https://developers.google.com/protocol-buffers/
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions are
- // met:
- //
- // * Redistributions of source code must retain the above copyright
- // notice, this list of conditions and the following disclaimer.
- // * Redistributions in binary form must reproduce the above
- // copyright notice, this list of conditions and the following disclaimer
- // in the documentation and/or other materials provided with the
- // distribution.
- // * Neither the name of Google Inc. nor the names of its
- // contributors may be used to endorse or promote products derived from
- // this software without specific prior written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- #include <google/protobuf/util/internal/protostream_objectsource.h>
- #include <memory>
- #include <sstream>
- #include <google/protobuf/stubs/casts.h>
- #include <google/protobuf/any.pb.h>
- #include <google/protobuf/io/coded_stream.h>
- #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
- #include <google/protobuf/descriptor.h>
- #include <google/protobuf/util/internal/expecting_objectwriter.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/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/type_info_test_helper.h>
- #include <google/protobuf/util/internal/constants.h>
- #include <google/protobuf/stubs/strutil.h>
- #include <gtest/gtest.h>
- namespace google {
- namespace protobuf {
- namespace util {
- namespace converter {
- using google::protobuf::Descriptor;
- using google::protobuf::DescriptorPool;
- using google::protobuf::FileDescriptorProto;
- using google::protobuf::Message;
- using google::protobuf::io::ArrayInputStream;
- using google::protobuf::io::CodedInputStream;
- using util::Status;
- using google::protobuf::testing::AnyM;
- using google::protobuf::testing::AnyOut;
- using google::protobuf::testing::Author;
- using google::protobuf::testing::BadAuthor;
- using google::protobuf::testing::BadNestedBook;
- using google::protobuf::testing::Book;
- using google::protobuf::testing::Book_Label;
- using google::protobuf::testing::Cyclic;
- using google::protobuf::testing::FieldMaskTest;
- using google::protobuf::testing::MapOut;
- using google::protobuf::testing::MapOutWireFormat;
- using google::protobuf::testing::NestedBook;
- using google::protobuf::testing::NestedFieldMask;
- using google::protobuf::testing::PackedPrimitive;
- using google::protobuf::testing::Primitive;
- using google::protobuf::testing::Proto3Message;
- using google::protobuf::testing::StructType;
- using google::protobuf::testing::TimestampDuration;
- using ::testing::_;
- namespace {
- string GetTypeUrl(const Descriptor* descriptor) {
- return string(kTypeServiceBaseUrl) + "/" + descriptor->full_name();
- }
- } // namespace
- class ProtostreamObjectSourceTest
- : public ::testing::TestWithParam<testing::TypeInfoSource> {
- protected:
- ProtostreamObjectSourceTest()
- : helper_(GetParam()),
- mock_(),
- ow_(&mock_),
- use_lower_camel_for_enums_(false),
- use_ints_for_enums_(false),
- add_trailing_zeros_(false),
- render_unknown_enum_values_(true) {
- helper_.ResetTypeInfo(Book::descriptor(), Proto3Message::descriptor());
- }
- virtual ~ProtostreamObjectSourceTest() {}
- void DoTest(const Message& msg, const Descriptor* descriptor) {
- Status status = ExecuteTest(msg, descriptor);
- EXPECT_EQ(util::Status(), status);
- }
- Status ExecuteTest(const Message& msg, const Descriptor* descriptor) {
- std::ostringstream oss;
- msg.SerializePartialToOstream(&oss);
- string proto = oss.str();
- ArrayInputStream arr_stream(proto.data(), proto.size());
- CodedInputStream in_stream(&arr_stream);
- std::unique_ptr<ProtoStreamObjectSource> os(
- helper_.NewProtoSource(&in_stream, GetTypeUrl(descriptor)));
- if (use_lower_camel_for_enums_) os->set_use_lower_camel_for_enums(true);
- if (use_ints_for_enums_) os->set_use_ints_for_enums(true);
- os->set_max_recursion_depth(64);
- return os->WriteTo(&mock_);
- }
- void PrepareExpectingObjectWriterForRepeatedPrimitive() {
- ow_.StartObject("")
- ->StartList("repFix32")
- ->RenderUint32("", bit_cast<uint32>(3201))
- ->RenderUint32("", bit_cast<uint32>(0))
- ->RenderUint32("", bit_cast<uint32>(3202))
- ->EndList()
- ->StartList("repU32")
- ->RenderUint32("", bit_cast<uint32>(3203))
- ->RenderUint32("", bit_cast<uint32>(0))
- ->EndList()
- ->StartList("repI32")
- ->RenderInt32("", 0)
- ->RenderInt32("", 3204)
- ->RenderInt32("", 3205)
- ->EndList()
- ->StartList("repSf32")
- ->RenderInt32("", 3206)
- ->RenderInt32("", 0)
- ->EndList()
- ->StartList("repS32")
- ->RenderInt32("", 0)
- ->RenderInt32("", 3207)
- ->RenderInt32("", 3208)
- ->EndList()
- ->StartList("repFix64")
- ->RenderUint64("", bit_cast<uint64>(6401LL))
- ->RenderUint64("", bit_cast<uint64>(0LL))
- ->EndList()
- ->StartList("repU64")
- ->RenderUint64("", bit_cast<uint64>(0LL))
- ->RenderUint64("", bit_cast<uint64>(6402LL))
- ->RenderUint64("", bit_cast<uint64>(6403LL))
- ->EndList()
- ->StartList("repI64")
- ->RenderInt64("", 6404L)
- ->RenderInt64("", 0L)
- ->EndList()
- ->StartList("repSf64")
- ->RenderInt64("", 0L)
- ->RenderInt64("", 6405L)
- ->RenderInt64("", 6406L)
- ->EndList()
- ->StartList("repS64")
- ->RenderInt64("", 6407L)
- ->RenderInt64("", 0L)
- ->EndList()
- ->StartList("repFloat")
- ->RenderFloat("", 0.0f)
- ->RenderFloat("", 32.1f)
- ->RenderFloat("", 32.2f)
- ->EndList()
- ->StartList("repDouble")
- ->RenderDouble("", 64.1L)
- ->RenderDouble("", 0.0L)
- ->EndList()
- ->StartList("repBool")
- ->RenderBool("", true)
- ->RenderBool("", false)
- ->EndList()
- ->EndObject();
- }
- Primitive PrepareRepeatedPrimitive() {
- Primitive primitive;
- primitive.add_rep_fix32(3201);
- primitive.add_rep_fix32(0);
- primitive.add_rep_fix32(3202);
- primitive.add_rep_u32(3203);
- primitive.add_rep_u32(0);
- primitive.add_rep_i32(0);
- primitive.add_rep_i32(3204);
- primitive.add_rep_i32(3205);
- primitive.add_rep_sf32(3206);
- primitive.add_rep_sf32(0);
- primitive.add_rep_s32(0);
- primitive.add_rep_s32(3207);
- primitive.add_rep_s32(3208);
- primitive.add_rep_fix64(6401L);
- primitive.add_rep_fix64(0L);
- primitive.add_rep_u64(0L);
- primitive.add_rep_u64(6402L);
- primitive.add_rep_u64(6403L);
- primitive.add_rep_i64(6404L);
- primitive.add_rep_i64(0L);
- primitive.add_rep_sf64(0L);
- primitive.add_rep_sf64(6405L);
- primitive.add_rep_sf64(6406L);
- primitive.add_rep_s64(6407L);
- primitive.add_rep_s64(0L);
- primitive.add_rep_float(0.0f);
- primitive.add_rep_float(32.1f);
- primitive.add_rep_float(32.2f);
- primitive.add_rep_double(64.1L);
- primitive.add_rep_double(0.0);
- primitive.add_rep_bool(true);
- primitive.add_rep_bool(false);
- PrepareExpectingObjectWriterForRepeatedPrimitive();
- return primitive;
- }
- PackedPrimitive PreparePackedPrimitive() {
- PackedPrimitive primitive;
- primitive.add_rep_fix32(3201);
- primitive.add_rep_fix32(0);
- primitive.add_rep_fix32(3202);
- primitive.add_rep_u32(3203);
- primitive.add_rep_u32(0);
- primitive.add_rep_i32(0);
- primitive.add_rep_i32(3204);
- primitive.add_rep_i32(3205);
- primitive.add_rep_sf32(3206);
- primitive.add_rep_sf32(0);
- primitive.add_rep_s32(0);
- primitive.add_rep_s32(3207);
- primitive.add_rep_s32(3208);
- primitive.add_rep_fix64(6401L);
- primitive.add_rep_fix64(0L);
- primitive.add_rep_u64(0L);
- primitive.add_rep_u64(6402L);
- primitive.add_rep_u64(6403L);
- primitive.add_rep_i64(6404L);
- primitive.add_rep_i64(0L);
- primitive.add_rep_sf64(0L);
- primitive.add_rep_sf64(6405L);
- primitive.add_rep_sf64(6406L);
- primitive.add_rep_s64(6407L);
- primitive.add_rep_s64(0L);
- primitive.add_rep_float(0.0f);
- primitive.add_rep_float(32.1f);
- primitive.add_rep_float(32.2f);
- primitive.add_rep_double(64.1L);
- primitive.add_rep_double(0.0);
- primitive.add_rep_bool(true);
- primitive.add_rep_bool(false);
- PrepareExpectingObjectWriterForRepeatedPrimitive();
- return primitive;
- }
- void UseLowerCamelForEnums() { use_lower_camel_for_enums_ = true; }
- void UseIntsForEnums() { use_ints_for_enums_ = true; }
- void AddTrailingZeros() { add_trailing_zeros_ = true; }
- void SetRenderUnknownEnumValues(bool value) {
- render_unknown_enum_values_ = value;
- }
- testing::TypeInfoTestHelper helper_;
- ::testing::NiceMock<MockObjectWriter> mock_;
- ExpectingObjectWriter ow_;
- bool use_lower_camel_for_enums_;
- bool use_ints_for_enums_;
- bool add_trailing_zeros_;
- bool render_unknown_enum_values_;
- };
- INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
- ProtostreamObjectSourceTest,
- ::testing::Values(
- testing::USE_TYPE_RESOLVER));
- TEST_P(ProtostreamObjectSourceTest, EmptyMessage) {
- Book empty;
- ow_.StartObject("")->EndObject();
- DoTest(empty, Book::descriptor());
- }
- TEST_P(ProtostreamObjectSourceTest, Primitives) {
- Primitive primitive;
- primitive.set_fix32(3201);
- primitive.set_u32(3202);
- primitive.set_i32(3203);
- primitive.set_sf32(3204);
- primitive.set_s32(3205);
- primitive.set_fix64(6401L);
- primitive.set_u64(6402L);
- primitive.set_i64(6403L);
- primitive.set_sf64(6404L);
- primitive.set_s64(6405L);
- primitive.set_str("String Value");
- primitive.set_bytes("Some Bytes");
- primitive.set_float_(32.1f);
- primitive.set_double_(64.1L);
- primitive.set_bool_(true);
- ow_.StartObject("")
- ->RenderUint32("fix32", bit_cast<uint32>(3201))
- ->RenderUint32("u32", bit_cast<uint32>(3202))
- ->RenderInt32("i32", 3203)
- ->RenderInt32("sf32", 3204)
- ->RenderInt32("s32", 3205)
- ->RenderUint64("fix64", bit_cast<uint64>(6401LL))
- ->RenderUint64("u64", bit_cast<uint64>(6402LL))
- ->RenderInt64("i64", 6403L)
- ->RenderInt64("sf64", 6404L)
- ->RenderInt64("s64", 6405L)
- ->RenderString("str", "String Value")
- ->RenderBytes("bytes", "Some Bytes")
- ->RenderFloat("float", 32.1f)
- ->RenderDouble("double", 64.1L)
- ->RenderBool("bool", true)
- ->EndObject();
- DoTest(primitive, Primitive::descriptor());
- }
- TEST_P(ProtostreamObjectSourceTest, RepeatingPrimitives) {
- Primitive primitive = PrepareRepeatedPrimitive();
- primitive.add_rep_str("String One");
- primitive.add_rep_str("String Two");
- primitive.add_rep_bytes("Some Bytes");
- ow_.StartList("repStr")
- ->RenderString("", "String One")
- ->RenderString("", "String Two")
- ->EndList()
- ->StartList("repBytes")
- ->RenderBytes("", "Some Bytes")
- ->EndList();
- DoTest(primitive, Primitive::descriptor());
- }
- TEST_P(ProtostreamObjectSourceTest, CustomJsonName) {
- Author author;
- author.set_id(12345);
- ow_.StartObject("")->RenderUint64("@id", 12345)->EndObject();
- DoTest(author, Author::descriptor());
- }
- TEST_P(ProtostreamObjectSourceTest, NestedMessage) {
- Author* author = new Author();
- author->set_name("Tolstoy");
- Book book;
- book.set_title("My Book");
- book.set_allocated_author(author);
- ow_.StartObject("")
- ->RenderString("title", "My Book")
- ->StartObject("author")
- ->RenderString("name", "Tolstoy")
- ->EndObject()
- ->EndObject();
- DoTest(book, Book::descriptor());
- }
- TEST_P(ProtostreamObjectSourceTest, RepeatingField) {
- Author author;
- author.set_alive(false);
- author.set_name("john");
- author.add_pseudonym("phil");
- author.add_pseudonym("bob");
- ow_.StartObject("")
- ->RenderBool("alive", false)
- ->RenderString("name", "john")
- ->StartList("pseudonym")
- ->RenderString("", "phil")
- ->RenderString("", "bob")
- ->EndList()
- ->EndObject();
- DoTest(author, Author::descriptor());
- }
- TEST_P(ProtostreamObjectSourceTest, PackedRepeatingFields) {
- DoTest(PreparePackedPrimitive(), PackedPrimitive::descriptor());
- }
- TEST_P(ProtostreamObjectSourceTest, NonPackedPackableFieldsActuallyPacked) {
- // Protostream is packed, but parse with non-packed Primitive.
- DoTest(PreparePackedPrimitive(), Primitive::descriptor());
- }
- TEST_P(ProtostreamObjectSourceTest, PackedPackableFieldNotActuallyPacked) {
- // Protostream is not packed, but parse with PackedPrimitive.
- DoTest(PrepareRepeatedPrimitive(), PackedPrimitive::descriptor());
- }
- TEST_P(ProtostreamObjectSourceTest, BadAuthor) {
- Author author;
- author.set_alive(false);
- author.set_name("john");
- author.set_id(1234L);
- author.add_pseudonym("phil");
- author.add_pseudonym("bob");
- ow_.StartObject("")
- ->StartList("alive")
- ->RenderBool("", false)
- ->EndList()
- ->StartList("name")
- ->RenderUint64("", static_cast<uint64>('j'))
- ->RenderUint64("", static_cast<uint64>('o'))
- ->RenderUint64("", static_cast<uint64>('h'))
- ->RenderUint64("", static_cast<uint64>('n'))
- ->EndList()
- ->RenderString("pseudonym", "phil")
- ->RenderString("pseudonym", "bob")
- ->EndObject();
- // Protostream created with Author, but parsed with BadAuthor.
- DoTest(author, BadAuthor::descriptor());
- }
- TEST_P(ProtostreamObjectSourceTest, NestedBookToBadNestedBook) {
- Book* book = new Book();
- book->set_length(250);
- book->set_published(2014L);
- NestedBook nested;
- nested.set_allocated_book(book);
- ow_.StartObject("")
- ->StartList("book")
- ->RenderUint32("", 24) // tag for field length (3 << 3)
- ->RenderUint32("", 250)
- ->RenderUint32("", 32) // tag for field published (4 << 3)
- ->RenderUint32("", 2014)
- ->EndList()
- ->EndObject();
- // Protostream created with NestedBook, but parsed with BadNestedBook.
- DoTest(nested, BadNestedBook::descriptor());
- }
- TEST_P(ProtostreamObjectSourceTest, BadNestedBookToNestedBook) {
- BadNestedBook nested;
- nested.add_book(1);
- nested.add_book(2);
- nested.add_book(3);
- nested.add_book(4);
- nested.add_book(5);
- nested.add_book(6);
- nested.add_book(7);
- ow_.StartObject("")->StartObject("book")->EndObject()->EndObject();
- // Protostream created with BadNestedBook, but parsed with NestedBook.
- DoTest(nested, NestedBook::descriptor());
- }
- TEST_P(ProtostreamObjectSourceTest,
- LongRepeatedListDoesNotBreakIntoMultipleJsonLists) {
- Book book;
- int repeat = 10000;
- for (int i = 0; i < repeat; ++i) {
- Book_Label* label = book.add_labels();
- label->set_key(StrCat("i", i));
- label->set_value(StrCat("v", i));
- }
- // Make sure StartList and EndList are called exactly once (see b/18227499 for
- // problems when this doesn't happen)
- EXPECT_CALL(mock_, StartList(_)).Times(1);
- EXPECT_CALL(mock_, EndList()).Times(1);
- DoTest(book, Book::descriptor());
- }
- TEST_P(ProtostreamObjectSourceTest, LowerCamelEnumOutputMacroCase) {
- Book book;
- book.set_type(Book::ACTION_AND_ADVENTURE);
- UseLowerCamelForEnums();
- ow_.StartObject("")->RenderString("type", "actionAndAdventure")->EndObject();
- DoTest(book, Book::descriptor());
- }
- TEST_P(ProtostreamObjectSourceTest, LowerCamelEnumOutputSnakeCase) {
- Book book;
- book.set_type(Book::arts_and_photography);
- UseLowerCamelForEnums();
- ow_.StartObject("")->RenderString("type", "artsAndPhotography")->EndObject();
- DoTest(book, Book::descriptor());
- }
- TEST_P(ProtostreamObjectSourceTest, LowerCamelEnumOutputWithNumber) {
- Book book;
- book.set_type(Book::I18N_Tech);
- UseLowerCamelForEnums();
- ow_.StartObject("")->RenderString("type", "i18nTech")->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, UseIntsForEnumsTest) {
- Book book;
- book.set_type(Book::ACTION_AND_ADVENTURE);
- UseIntsForEnums();
- ow_.StartObject("")->RenderInt32("type", 3)->EndObject();
- DoTest(book, Book::descriptor());
- }
- TEST_P(ProtostreamObjectSourceTest,
- UnknownEnumAreDroppedWhenRenderUnknownEnumValuesIsUnset) {
- Proto3Message message;
- message.set_enum_value(static_cast<Proto3Message::NestedEnum>(1234));
- SetRenderUnknownEnumValues(false);
- // Unknown enum values are not output.
- ow_.StartObject("")->EndObject();
- DoTest(message, Proto3Message::descriptor());
- }
- TEST_P(ProtostreamObjectSourceTest,
- UnknownEnumAreOutputWhenRenderUnknownEnumValuesIsSet) {
- Proto3Message message;
- message.set_enum_value(static_cast<Proto3Message::NestedEnum>(1234));
- SetRenderUnknownEnumValues(true);
- // Unknown enum values are output.
- ow_.StartObject("")->RenderInt32("enumValue", 1234)->EndObject();
- DoTest(message, Proto3Message::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() {
- helper_.ResetTypeInfo(MapOut::descriptor());
- }
- };
- INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
- ProtostreamObjectSourceMapsTest,
- ::testing::Values(
- testing::USE_TYPE_RESOLVER));
- // Tests JSON map.
- //
- // This is the example expected output.
- // {
- // "map1": {
- // "key1": {
- // "foo": "foovalue"
- // },
- // "key2": {
- // "foo": "barvalue"
- // }
- // },
- // "map2": {
- // "nestedself": {
- // "map1": {
- // "nested_key1": {
- // "foo": "nested_foo"
- // }
- // },
- // "bar": "nested_bar_string"
- // }
- // },
- // "map3": {
- // "111": "one one one"
- // },
- // "bar": "top bar"
- // }
- TEST_P(ProtostreamObjectSourceMapsTest, MapsTest) {
- MapOut out;
- (*out.mutable_map1())["key1"].set_foo("foovalue");
- (*out.mutable_map1())["key2"].set_foo("barvalue");
- MapOut* nested_value = &(*out.mutable_map2())["nestedself"];
- (*nested_value->mutable_map1())["nested_key1"].set_foo("nested_foo");
- nested_value->set_bar("nested_bar_string");
- (*out.mutable_map3())[111] = "one one one";
- out.set_bar("top bar");
- ow_.StartObject("")
- ->StartObject("map1")
- ->StartObject("key1")
- ->RenderString("foo", "foovalue")
- ->EndObject()
- ->StartObject("key2")
- ->RenderString("foo", "barvalue")
- ->EndObject()
- ->StartObject("map2")
- ->StartObject("nestedself")
- ->StartObject("map1")
- ->StartObject("nested_key1")
- ->RenderString("foo", "nested_foo")
- ->EndObject()
- ->EndObject()
- ->RenderString("bar", "nested_bar_string")
- ->EndObject()
- ->EndObject()
- ->StartObject("map3")
- ->RenderString("111", "one one one")
- ->EndObject()
- ->EndObject()
- ->RenderString("bar", "top bar")
- ->EndObject();
- 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() {
- helper_.ResetTypeInfo(AnyOut::descriptor(),
- google::protobuf::Any::descriptor());
- }
- };
- INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
- ProtostreamObjectSourceAnysTest,
- ::testing::Values(
- testing::USE_TYPE_RESOLVER));
- // Tests JSON any support.
- //
- // This is the example expected output.
- // {
- // "any": {
- // "@type": "type.googleapis.com/google.protobuf.testing.AnyM"
- // "foo": "foovalue"
- // }
- // }
- TEST_P(ProtostreamObjectSourceAnysTest, BasicAny) {
- AnyOut out;
- ::google::protobuf::Any* any = out.mutable_any();
- AnyM m;
- m.set_foo("foovalue");
- any->PackFrom(m);
- ow_.StartObject("")
- ->StartObject("any")
- ->RenderString("@type",
- "type.googleapis.com/google.protobuf.testing.AnyM")
- ->RenderString("foo", "foovalue")
- ->EndObject()
- ->EndObject();
- DoTest(out, AnyOut::descriptor());
- }
- TEST_P(ProtostreamObjectSourceAnysTest, RecursiveAny) {
- AnyOut out;
- ::google::protobuf::Any* any = out.mutable_any();
- 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.AnyM");
- AnyM m;
- m.set_foo("foovalue");
- nested_any.set_value(m.SerializeAsString());
- any->set_value(nested_any.SerializeAsString());
- ow_.StartObject("")
- ->StartObject("any")
- ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
- ->StartObject("value")
- ->RenderString("@type",
- "type.googleapis.com/google.protobuf.testing.AnyM")
- ->RenderString("foo", "foovalue")
- ->EndObject()
- ->EndObject()
- ->EndObject();
- DoTest(out, AnyOut::descriptor());
- }
- TEST_P(ProtostreamObjectSourceAnysTest, DoubleRecursiveAny) {
- AnyOut out;
- ::google::protobuf::Any* any = out.mutable_any();
- 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.Any");
- ::google::protobuf::Any second_nested_any;
- second_nested_any.set_type_url(
- "type.googleapis.com/google.protobuf.testing.AnyM");
- AnyM m;
- m.set_foo("foovalue");
- second_nested_any.set_value(m.SerializeAsString());
- nested_any.set_value(second_nested_any.SerializeAsString());
- any->set_value(nested_any.SerializeAsString());
- ow_.StartObject("")
- ->StartObject("any")
- ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
- ->StartObject("value")
- ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
- ->StartObject("value")
- ->RenderString("@type",
- "type.googleapis.com/google.protobuf.testing.AnyM")
- ->RenderString("foo", "foovalue")
- ->EndObject()
- ->EndObject()
- ->EndObject()
- ->EndObject();
- DoTest(out, AnyOut::descriptor());
- }
- TEST_P(ProtostreamObjectSourceAnysTest, EmptyAnyOutputsEmptyObject) {
- AnyOut out;
- out.mutable_any();
- ow_.StartObject("")->StartObject("any")->EndObject()->EndObject();
- DoTest(out, AnyOut::descriptor());
- }
- TEST_P(ProtostreamObjectSourceAnysTest, EmptyWithTypeAndNoValueOutputsType) {
- AnyOut out;
- out.mutable_any()->set_type_url("foo.googleapis.com/my.Type");
- ow_.StartObject("")
- ->StartObject("any")
- ->RenderString("@type", "foo.googleapis.com/my.Type")
- ->EndObject()
- ->EndObject();
- DoTest(out, AnyOut::descriptor());
- }
- TEST_P(ProtostreamObjectSourceAnysTest, MissingTypeUrlError) {
- AnyOut out;
- ::google::protobuf::Any* any = out.mutable_any();
- AnyM m;
- m.set_foo("foovalue");
- any->set_value(m.SerializeAsString());
- // We start the "AnyOut" part and then fail when we hit the Any object.
- ow_.StartObject("");
- Status status = ExecuteTest(out, AnyOut::descriptor());
- EXPECT_EQ(util::error::INTERNAL, status.error_code());
- }
- TEST_P(ProtostreamObjectSourceAnysTest, UnknownTypeServiceError) {
- AnyOut out;
- ::google::protobuf::Any* any = out.mutable_any();
- any->set_type_url("foo.googleapis.com/my.own.Type");
- AnyM m;
- m.set_foo("foovalue");
- any->set_value(m.SerializeAsString());
- // We start the "AnyOut" part and then fail when we hit the Any object.
- ow_.StartObject("");
- Status status = ExecuteTest(out, AnyOut::descriptor());
- EXPECT_EQ(util::error::INTERNAL, status.error_code());
- }
- TEST_P(ProtostreamObjectSourceAnysTest, UnknownTypeError) {
- AnyOut out;
- ::google::protobuf::Any* any = out.mutable_any();
- any->set_type_url("type.googleapis.com/unknown.Type");
- AnyM m;
- m.set_foo("foovalue");
- any->set_value(m.SerializeAsString());
- // We start the "AnyOut" part and then fail when we hit the Any object.
- ow_.StartObject("");
- Status status = ExecuteTest(out, AnyOut::descriptor());
- EXPECT_EQ(util::error::INTERNAL, status.error_code());
- }
- class ProtostreamObjectSourceStructTest : public ProtostreamObjectSourceTest {
- protected:
- ProtostreamObjectSourceStructTest() {
- helper_.ResetTypeInfo(StructType::descriptor(),
- google::protobuf::Struct::descriptor());
- }
- };
- INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
- ProtostreamObjectSourceStructTest,
- ::testing::Values(
- testing::USE_TYPE_RESOLVER));
- // Tests struct
- //
- // "object": {
- // "k1": 123,
- // "k2": true
- // }
- TEST_P(ProtostreamObjectSourceStructTest, StructRenderSuccess) {
- StructType out;
- google::protobuf::Struct* s = out.mutable_object();
- s->mutable_fields()->operator[]("k1").set_number_value(123);
- s->mutable_fields()->operator[]("k2").set_bool_value(true);
- ow_.StartObject("")
- ->StartObject("object")
- ->RenderDouble("k1", 123)
- ->RenderBool("k2", true)
- ->EndObject()
- ->EndObject();
- DoTest(out, StructType::descriptor());
- }
- TEST_P(ProtostreamObjectSourceStructTest, MissingValueSkipsField) {
- StructType out;
- google::protobuf::Struct* s = out.mutable_object();
- s->mutable_fields()->operator[]("k1");
- ow_.StartObject("")->StartObject("object")->EndObject()->EndObject();
- DoTest(out, StructType::descriptor());
- }
- class ProtostreamObjectSourceFieldMaskTest
- : public ProtostreamObjectSourceTest {
- protected:
- ProtostreamObjectSourceFieldMaskTest() {
- helper_.ResetTypeInfo(FieldMaskTest::descriptor(),
- google::protobuf::FieldMask::descriptor());
- }
- };
- INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
- ProtostreamObjectSourceFieldMaskTest,
- ::testing::Values(
- testing::USE_TYPE_RESOLVER));
- TEST_P(ProtostreamObjectSourceFieldMaskTest, FieldMaskRenderSuccess) {
- FieldMaskTest out;
- out.set_id("1");
- out.mutable_single_mask()->add_paths("path1");
- out.mutable_single_mask()->add_paths("snake_case_path2");
- ::google::protobuf::FieldMask* mask = out.add_repeated_mask();
- mask->add_paths("path3");
- mask = out.add_repeated_mask();
- mask->add_paths("snake_case_path4");
- mask->add_paths("path5");
- NestedFieldMask* nested = out.add_nested_mask();
- nested->set_data("data");
- nested->mutable_single_mask()->add_paths("nested.path1");
- nested->mutable_single_mask()->add_paths("nested_field.snake_case_path2");
- mask = nested->add_repeated_mask();
- mask->add_paths("nested_field.path3");
- mask->add_paths("nested.snake_case_path4");
- mask = nested->add_repeated_mask();
- mask->add_paths("nested.path5");
- mask = nested->add_repeated_mask();
- mask->add_paths(
- "snake_case.map_field[\"map_key_should_be_ignored\"].nested_snake_case."
- "map_field[\"map_key_sho\\\"uld_be_ignored\"]");
- ow_.StartObject("")
- ->RenderString("id", "1")
- ->RenderString("singleMask", "path1,snakeCasePath2")
- ->StartList("repeatedMask")
- ->RenderString("", "path3")
- ->RenderString("", "snakeCasePath4,path5")
- ->EndList()
- ->StartList("nestedMask")
- ->StartObject("")
- ->RenderString("data", "data")
- ->RenderString("singleMask", "nested.path1,nestedField.snakeCasePath2")
- ->StartList("repeatedMask")
- ->RenderString("", "nestedField.path3,nested.snakeCasePath4")
- ->RenderString("", "nested.path5")
- ->RenderString("",
- "snakeCase.mapField[\"map_key_should_be_ignored\"]."
- "nestedSnakeCase.mapField[\"map_key_sho\\\"uld_be_"
- "ignored\"]")
- ->EndList()
- ->EndObject()
- ->EndList()
- ->EndObject();
- 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());
- }
- TEST_P(ProtostreamObjectSourceTimestampTest, TimestampDurationDefaultValue) {
- TimestampDuration out;
- out.mutable_ts()->set_seconds(0);
- out.mutable_dur()->set_seconds(0);
- ow_.StartObject("")
- ->RenderString("ts", "1970-01-01T00:00:00Z")
- ->RenderString("dur", "0s")
- ->EndObject();
- DoTest(out, TimestampDuration::descriptor());
- }
- } // namespace converter
- } // namespace util
- } // namespace protobuf
- } // namespace google
|