protostream_objectwriter_test.cc 85 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  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. #include <google/protobuf/util/internal/protostream_objectwriter.h>
  31. #include <stddef.h> // For size_t
  32. #include <google/protobuf/field_mask.pb.h>
  33. #include <google/protobuf/timestamp.pb.h>
  34. #include <google/protobuf/wrappers.pb.h>
  35. #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
  36. #include <google/protobuf/descriptor.pb.h>
  37. #include <google/protobuf/descriptor.h>
  38. #include <google/protobuf/dynamic_message.h>
  39. #include <google/protobuf/message.h>
  40. #include <google/protobuf/util/internal/mock_error_listener.h>
  41. #include <google/protobuf/util/internal/testdata/anys.pb.h>
  42. #include <google/protobuf/util/internal/testdata/books.pb.h>
  43. #include <google/protobuf/util/internal/testdata/field_mask.pb.h>
  44. #include <google/protobuf/util/internal/testdata/maps.pb.h>
  45. #include <google/protobuf/util/internal/testdata/oneofs.pb.h>
  46. #include <google/protobuf/util/internal/testdata/proto3.pb.h>
  47. #include <google/protobuf/util/internal/testdata/struct.pb.h>
  48. #include <google/protobuf/util/internal/testdata/timestamp_duration.pb.h>
  49. #include <google/protobuf/util/internal/testdata/wrappers.pb.h>
  50. #include <google/protobuf/util/internal/type_info_test_helper.h>
  51. #include <google/protobuf/util/internal/constants.h>
  52. #include <google/protobuf/util/message_differencer.h>
  53. #include <google/protobuf/stubs/bytestream.h>
  54. #include <google/protobuf/stubs/strutil.h>
  55. #include <gtest/gtest.h>
  56. namespace google {
  57. namespace protobuf {
  58. namespace util {
  59. namespace converter {
  60. using google::protobuf::testing::AnyM;
  61. using google::protobuf::testing::AnyOut;
  62. using google::protobuf::testing::Author;
  63. using google::protobuf::testing::Book;
  64. using google::protobuf::testing::FieldMaskTest;
  65. using google::protobuf::testing::Int32Wrapper;
  66. using google::protobuf::testing::MapIn;
  67. using google::protobuf::testing::Primitive;
  68. using google::protobuf::testing::Proto3Message;
  69. using google::protobuf::testing::Publisher;
  70. using google::protobuf::testing::StructType;
  71. using google::protobuf::testing::TestJsonName1;
  72. using google::protobuf::testing::TestJsonName2;
  73. using google::protobuf::testing::TimestampDuration;
  74. using google::protobuf::testing::ValueWrapper;
  75. using google::protobuf::testing::oneofs::OneOfsRequest;
  76. using google::protobuf::Descriptor;
  77. using google::protobuf::DescriptorPool;
  78. using google::protobuf::DynamicMessageFactory;
  79. using google::protobuf::FileDescriptorProto;
  80. using google::protobuf::Message;
  81. using strings::GrowingArrayByteSink;
  82. using ::testing::_;
  83. using ::testing::Args;
  84. namespace {
  85. string GetTypeUrl(const Descriptor* descriptor) {
  86. return string(kTypeServiceBaseUrl) + "/" + descriptor->full_name();
  87. }
  88. } // namespace
  89. #if __cplusplus >= 201103L
  90. using std::get;
  91. #else
  92. using std::tr1::get;
  93. #endif
  94. class BaseProtoStreamObjectWriterTest
  95. : public ::testing::TestWithParam<testing::TypeInfoSource> {
  96. protected:
  97. BaseProtoStreamObjectWriterTest()
  98. : helper_(GetParam()),
  99. listener_(),
  100. output_(new GrowingArrayByteSink(1000)),
  101. ow_() {}
  102. explicit BaseProtoStreamObjectWriterTest(const Descriptor* descriptor)
  103. : helper_(GetParam()),
  104. listener_(),
  105. output_(new GrowingArrayByteSink(1000)),
  106. ow_() {
  107. std::vector<const Descriptor*> descriptors;
  108. descriptors.push_back(descriptor);
  109. ResetTypeInfo(descriptors);
  110. }
  111. explicit BaseProtoStreamObjectWriterTest(
  112. std::vector<const Descriptor*> descriptors)
  113. : helper_(GetParam()),
  114. listener_(),
  115. output_(new GrowingArrayByteSink(1000)),
  116. ow_() {
  117. ResetTypeInfo(descriptors);
  118. }
  119. void ResetTypeInfo(std::vector<const Descriptor*> descriptors) {
  120. GOOGLE_CHECK(!descriptors.empty()) << "Must have at least one descriptor!";
  121. helper_.ResetTypeInfo(descriptors);
  122. ow_.reset(helper_.NewProtoWriter(GetTypeUrl(descriptors[0]), output_.get(),
  123. &listener_, options_));
  124. }
  125. void ResetTypeInfo(const Descriptor* descriptor) {
  126. std::vector<const Descriptor*> descriptors;
  127. descriptors.push_back(descriptor);
  128. ResetTypeInfo(descriptors);
  129. }
  130. virtual ~BaseProtoStreamObjectWriterTest() {}
  131. void CheckOutput(const Message& expected, int expected_length) {
  132. size_t nbytes;
  133. std::unique_ptr<char[]> buffer(output_->GetBuffer(&nbytes));
  134. if (expected_length >= 0) {
  135. EXPECT_EQ(expected_length, nbytes);
  136. }
  137. string str(buffer.get(), nbytes);
  138. std::stringbuf str_buf(str, std::ios_base::in);
  139. std::istream istream(&str_buf);
  140. std::unique_ptr<Message> message(expected.New());
  141. message->ParsePartialFromIstream(&istream);
  142. if (!MessageDifferencer::Equivalent(expected, *message)) {
  143. EXPECT_EQ(expected.DebugString(), message->DebugString());
  144. }
  145. }
  146. void CheckOutput(const Message& expected) { CheckOutput(expected, -1); }
  147. const google::protobuf::Type* GetType(const Descriptor* descriptor) {
  148. return helper_.GetTypeInfo()->GetTypeByTypeUrl(GetTypeUrl(descriptor));
  149. }
  150. testing::TypeInfoTestHelper helper_;
  151. MockErrorListener listener_;
  152. std::unique_ptr<GrowingArrayByteSink> output_;
  153. std::unique_ptr<ProtoStreamObjectWriter> ow_;
  154. ProtoStreamObjectWriter::Options options_;
  155. };
  156. MATCHER_P(HasObjectLocation, expected,
  157. "Verifies the expected object location") {
  158. string actual = get<0>(arg).ToString();
  159. if (actual.compare(expected) == 0) return true;
  160. *result_listener << "actual location is: " << actual;
  161. return false;
  162. }
  163. class ProtoStreamObjectWriterTest : public BaseProtoStreamObjectWriterTest {
  164. protected:
  165. ProtoStreamObjectWriterTest()
  166. : BaseProtoStreamObjectWriterTest(Book::descriptor()) {}
  167. void ResetProtoWriter() {
  168. ResetTypeInfo(Book::descriptor());
  169. }
  170. virtual ~ProtoStreamObjectWriterTest() {}
  171. };
  172. INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
  173. ProtoStreamObjectWriterTest,
  174. ::testing::Values(
  175. testing::USE_TYPE_RESOLVER));
  176. TEST_P(ProtoStreamObjectWriterTest, EmptyObject) {
  177. Book empty;
  178. ow_->StartObject("")->EndObject();
  179. CheckOutput(empty, 0);
  180. }
  181. TEST_P(ProtoStreamObjectWriterTest, SimpleObject) {
  182. string content("My content");
  183. Book book;
  184. book.set_title("My Title");
  185. book.set_length(222);
  186. book.set_content(content);
  187. ow_->StartObject("")
  188. ->RenderString("title", "My Title")
  189. ->RenderInt32("length", 222)
  190. ->RenderBytes("content", content)
  191. ->EndObject();
  192. CheckOutput(book);
  193. }
  194. TEST_P(ProtoStreamObjectWriterTest, SimpleMessage) {
  195. Book book;
  196. book.set_title("Some Book");
  197. book.set_length(102);
  198. Publisher* publisher = book.mutable_publisher();
  199. publisher->set_name("My Publisher");
  200. Author* robert = book.mutable_author();
  201. robert->set_alive(true);
  202. robert->set_name("robert");
  203. robert->add_pseudonym("bob");
  204. robert->add_pseudonym("bobby");
  205. robert->add_friend_()->set_name("john");
  206. ow_->StartObject("")
  207. ->RenderString("title", "Some Book")
  208. ->RenderInt32("length", 102)
  209. ->StartObject("publisher")
  210. ->RenderString("name", "My Publisher")
  211. ->EndObject()
  212. ->StartObject("author")
  213. ->RenderBool("alive", true)
  214. ->RenderString("name", "robert")
  215. ->StartList("pseudonym")
  216. ->RenderString("", "bob")
  217. ->RenderString("", "bobby")
  218. ->EndList()
  219. ->StartList("friend")
  220. ->StartObject("")
  221. ->RenderString("name", "john")
  222. ->EndObject()
  223. ->EndList()
  224. ->EndObject()
  225. ->EndObject();
  226. CheckOutput(book);
  227. }
  228. TEST_P(ProtoStreamObjectWriterTest, CustomJsonName) {
  229. Book book;
  230. Author* robert = book.mutable_author();
  231. robert->set_id(12345);
  232. robert->set_name("robert");
  233. ow_->StartObject("")
  234. ->StartObject("author")
  235. ->RenderUint64("@id", 12345)
  236. ->RenderString("name", "robert")
  237. ->EndObject()
  238. ->EndObject();
  239. CheckOutput(book);
  240. }
  241. // Test that two messages can have different fields mapped to the same JSON
  242. // name. See: https://github.com/google/protobuf/issues/1415
  243. TEST_P(ProtoStreamObjectWriterTest, ConflictingJsonName) {
  244. ResetTypeInfo(TestJsonName1::descriptor());
  245. TestJsonName1 message1;
  246. message1.set_one_value(12345);
  247. ow_->StartObject("")->RenderInt32("value", 12345)->EndObject();
  248. CheckOutput(message1);
  249. ResetTypeInfo(TestJsonName2::descriptor());
  250. TestJsonName2 message2;
  251. message2.set_another_value(12345);
  252. ow_->StartObject("")->RenderInt32("value", 12345)->EndObject();
  253. CheckOutput(message2);
  254. }
  255. TEST_P(ProtoStreamObjectWriterTest, IntEnumValuesAreAccepted) {
  256. Book book;
  257. book.set_title("Some Book");
  258. book.set_type(google::protobuf::testing::Book_Type_KIDS);
  259. Author* robert = book.mutable_author();
  260. robert->set_name("robert");
  261. ow_->StartObject("")
  262. ->RenderString("title", "Some Book")
  263. ->RenderString("type", "2")
  264. ->StartObject("author")
  265. ->RenderString("name", "robert")
  266. ->EndObject()
  267. ->EndObject();
  268. CheckOutput(book);
  269. }
  270. TEST_P(ProtoStreamObjectWriterTest, EnumValuesWithoutUnderscoreAreAccepted) {
  271. Book book;
  272. book.set_title("Some Book");
  273. book.set_type(google::protobuf::testing::Book_Type_ACTION_AND_ADVENTURE);
  274. Author* robert = book.mutable_author();
  275. robert->set_name("robert");
  276. options_.use_lower_camel_for_enums = true;
  277. ResetProtoWriter();
  278. ow_->StartObject("")
  279. ->RenderString("title", "Some Book")
  280. ->RenderString("type", "ACTIONANDADVENTURE")
  281. ->StartObject("author")
  282. ->RenderString("name", "robert")
  283. ->EndObject()
  284. ->EndObject();
  285. CheckOutput(book);
  286. }
  287. TEST_P(ProtoStreamObjectWriterTest, EnumValuesInCamelCaseAreAccepted) {
  288. Book book;
  289. book.set_title("Some Book");
  290. book.set_type(google::protobuf::testing::Book_Type_ACTION_AND_ADVENTURE);
  291. Author* robert = book.mutable_author();
  292. robert->set_name("robert");
  293. options_.use_lower_camel_for_enums = true;
  294. ResetProtoWriter();
  295. ow_->StartObject("")
  296. ->RenderString("title", "Some Book")
  297. ->RenderString("type", "actionAndAdventure")
  298. ->StartObject("author")
  299. ->RenderString("name", "robert")
  300. ->EndObject()
  301. ->EndObject();
  302. CheckOutput(book);
  303. }
  304. TEST_P(ProtoStreamObjectWriterTest,
  305. EnumValuesInCamelCaseWithNameNotUppercaseAreAccepted) {
  306. Book book;
  307. book.set_title("Some Book");
  308. book.set_type(google::protobuf::testing::Book_Type_arts_and_photography);
  309. Author* robert = book.mutable_author();
  310. robert->set_name("robert");
  311. options_.use_lower_camel_for_enums = true;
  312. ResetProtoWriter();
  313. ow_->StartObject("")
  314. ->RenderString("title", "Some Book")
  315. ->RenderString("type", "artsAndPhotography")
  316. ->StartObject("author")
  317. ->RenderString("name", "robert")
  318. ->EndObject()
  319. ->EndObject();
  320. CheckOutput(book);
  321. }
  322. TEST_P(ProtoStreamObjectWriterTest, PrimitiveFromStringConversion) {
  323. Primitive full;
  324. full.set_fix32(101);
  325. full.set_u32(102);
  326. full.set_i32(-103);
  327. full.set_sf32(-104);
  328. full.set_s32(-105);
  329. full.set_fix64(40000000001L);
  330. full.set_u64(40000000002L);
  331. full.set_i64(-40000000003L);
  332. full.set_sf64(-40000000004L);
  333. full.set_s64(-40000000005L);
  334. full.set_str("string1");
  335. full.set_bytes("Some Bytes");
  336. full.set_float_(3.14f);
  337. full.set_double_(-4.05L);
  338. full.set_bool_(true);
  339. full.add_rep_fix32(201);
  340. full.add_rep_u32(202);
  341. full.add_rep_i32(-203);
  342. full.add_rep_sf32(-204);
  343. full.add_rep_s32(-205);
  344. full.add_rep_fix64(80000000001L);
  345. full.add_rep_u64(80000000002L);
  346. full.add_rep_i64(-80000000003L);
  347. full.add_rep_sf64(-80000000004L);
  348. full.add_rep_s64(-80000000005L);
  349. full.add_rep_str("string2");
  350. full.add_rep_bytes("More Bytes");
  351. full.add_rep_float(6.14f);
  352. full.add_rep_double(-8.05L);
  353. full.add_rep_bool(false);
  354. ResetTypeInfo(Primitive::descriptor());
  355. ow_->StartObject("")
  356. ->RenderString("fix32", "101")
  357. ->RenderString("u32", "102")
  358. ->RenderString("i32", "-103")
  359. ->RenderString("sf32", "-104")
  360. ->RenderString("s32", "-105")
  361. ->RenderString("fix64", "40000000001")
  362. ->RenderString("u64", "40000000002")
  363. ->RenderString("i64", "-40000000003")
  364. ->RenderString("sf64", "-40000000004")
  365. ->RenderString("s64", "-40000000005")
  366. ->RenderString("str", "string1")
  367. ->RenderString("bytes", "U29tZSBCeXRlcw==") // "Some Bytes"
  368. ->RenderString("float", "3.14")
  369. ->RenderString("double", "-4.05")
  370. ->RenderString("bool", "true")
  371. ->StartList("rep_fix32")
  372. ->RenderString("", "201")
  373. ->EndList()
  374. ->StartList("rep_u32")
  375. ->RenderString("", "202")
  376. ->EndList()
  377. ->StartList("rep_i32")
  378. ->RenderString("", "-203")
  379. ->EndList()
  380. ->StartList("rep_sf32")
  381. ->RenderString("", "-204")
  382. ->EndList()
  383. ->StartList("rep_s32")
  384. ->RenderString("", "-205")
  385. ->EndList()
  386. ->StartList("rep_fix64")
  387. ->RenderString("", "80000000001")
  388. ->EndList()
  389. ->StartList("rep_u64")
  390. ->RenderString("", "80000000002")
  391. ->EndList()
  392. ->StartList("rep_i64")
  393. ->RenderString("", "-80000000003")
  394. ->EndList()
  395. ->StartList("rep_sf64")
  396. ->RenderString("", "-80000000004")
  397. ->EndList()
  398. ->StartList("rep_s64")
  399. ->RenderString("", "-80000000005")
  400. ->EndList()
  401. ->StartList("rep_str")
  402. ->RenderString("", "string2")
  403. ->EndList()
  404. ->StartList("rep_bytes")
  405. ->RenderString("", "TW9yZSBCeXRlcw==") // "More Bytes"
  406. ->EndList()
  407. ->StartList("rep_float")
  408. ->RenderString("", "6.14")
  409. ->EndList()
  410. ->StartList("rep_double")
  411. ->RenderString("", "-8.05")
  412. ->EndList()
  413. ->StartList("rep_bool")
  414. ->RenderString("", "false")
  415. ->EndList()
  416. ->EndObject();
  417. CheckOutput(full);
  418. }
  419. TEST_P(ProtoStreamObjectWriterTest, InfinityInputTest) {
  420. Primitive full;
  421. full.set_double_(std::numeric_limits<double>::infinity());
  422. full.set_float_(std::numeric_limits<float>::infinity());
  423. full.set_str("-Infinity");
  424. ResetTypeInfo(Primitive::descriptor());
  425. EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_INT32"),
  426. StringPiece("\"Infinity\"")))
  427. .With(Args<0>(HasObjectLocation("i32")));
  428. EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_UINT32"),
  429. StringPiece("\"Infinity\"")))
  430. .With(Args<0>(HasObjectLocation("u32")));
  431. EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_SFIXED64"),
  432. StringPiece("\"-Infinity\"")))
  433. .With(Args<0>(HasObjectLocation("sf64")));
  434. EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_BOOL"),
  435. StringPiece("\"Infinity\"")))
  436. .With(Args<0>(HasObjectLocation("bool")));
  437. ow_->StartObject("")
  438. ->RenderString("double", "Infinity")
  439. ->RenderString("float", "Infinity")
  440. ->RenderString("i32", "Infinity")
  441. ->RenderString("u32", "Infinity")
  442. ->RenderString("sf64", "-Infinity")
  443. ->RenderString("str", "-Infinity")
  444. ->RenderString("bool", "Infinity")
  445. ->EndObject();
  446. CheckOutput(full);
  447. }
  448. TEST_P(ProtoStreamObjectWriterTest, NaNInputTest) {
  449. Primitive full;
  450. full.set_double_(std::numeric_limits<double>::quiet_NaN());
  451. full.set_float_(std::numeric_limits<float>::quiet_NaN());
  452. full.set_str("NaN");
  453. ResetTypeInfo(Primitive::descriptor());
  454. EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_INT32"),
  455. StringPiece("\"NaN\"")))
  456. .With(Args<0>(HasObjectLocation("i32")));
  457. EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_UINT32"),
  458. StringPiece("\"NaN\"")))
  459. .With(Args<0>(HasObjectLocation("u32")));
  460. EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_SFIXED64"),
  461. StringPiece("\"NaN\"")))
  462. .With(Args<0>(HasObjectLocation("sf64")));
  463. EXPECT_CALL(listener_,
  464. InvalidValue(_, StringPiece("TYPE_BOOL"), StringPiece("\"NaN\"")))
  465. .With(Args<0>(HasObjectLocation("bool")));
  466. ow_->StartObject("")
  467. ->RenderString("double", "NaN")
  468. ->RenderString("float", "NaN")
  469. ->RenderString("i32", "NaN")
  470. ->RenderString("u32", "NaN")
  471. ->RenderString("sf64", "NaN")
  472. ->RenderString("str", "NaN")
  473. ->RenderString("bool", "NaN")
  474. ->EndObject();
  475. CheckOutput(full);
  476. }
  477. TEST_P(ProtoStreamObjectWriterTest, ImplicitPrimitiveList) {
  478. Book expected;
  479. Author* author = expected.mutable_author();
  480. author->set_name("The Author");
  481. author->add_pseudonym("first");
  482. author->add_pseudonym("second");
  483. ow_->StartObject("")
  484. ->StartObject("author")
  485. ->RenderString("name", "The Author")
  486. ->RenderString("pseudonym", "first")
  487. ->RenderString("pseudonym", "second")
  488. ->EndObject()
  489. ->EndObject();
  490. CheckOutput(expected);
  491. }
  492. TEST_P(ProtoStreamObjectWriterTest,
  493. LastWriteWinsOnNonRepeatedPrimitiveFieldWithDuplicates) {
  494. Book expected;
  495. Author* author = expected.mutable_author();
  496. author->set_name("second");
  497. ow_->StartObject("")
  498. ->StartObject("author")
  499. ->RenderString("name", "first")
  500. ->RenderString("name", "second")
  501. ->EndObject()
  502. ->EndObject();
  503. CheckOutput(expected);
  504. }
  505. TEST_P(ProtoStreamObjectWriterTest, ExplicitPrimitiveList) {
  506. Book expected;
  507. Author* author = expected.mutable_author();
  508. author->set_name("The Author");
  509. author->add_pseudonym("first");
  510. author->add_pseudonym("second");
  511. ow_->StartObject("")
  512. ->StartObject("author")
  513. ->RenderString("name", "The Author")
  514. ->StartList("pseudonym")
  515. ->RenderString("", "first")
  516. ->RenderString("", "second")
  517. ->EndList()
  518. ->EndObject()
  519. ->EndObject();
  520. CheckOutput(expected);
  521. }
  522. TEST_P(ProtoStreamObjectWriterTest, NonRepeatedExplicitPrimitiveList) {
  523. Book expected;
  524. expected.set_allocated_author(new Author());
  525. EXPECT_CALL(
  526. listener_,
  527. InvalidName(
  528. _, StringPiece("name"),
  529. StringPiece("Proto field is not repeating, cannot start list.")))
  530. .With(Args<0>(HasObjectLocation("author")));
  531. ow_->StartObject("")
  532. ->StartObject("author")
  533. ->StartList("name")
  534. ->RenderString("", "first")
  535. ->RenderString("", "second")
  536. ->EndList()
  537. ->EndObject()
  538. ->EndObject();
  539. CheckOutput(expected);
  540. }
  541. TEST_P(ProtoStreamObjectWriterTest, ImplicitMessageList) {
  542. Book expected;
  543. Author* outer = expected.mutable_author();
  544. outer->set_name("outer");
  545. outer->set_alive(true);
  546. Author* first = outer->add_friend_();
  547. first->set_name("first");
  548. Author* second = outer->add_friend_();
  549. second->set_name("second");
  550. ow_->StartObject("")
  551. ->StartObject("author")
  552. ->RenderString("name", "outer")
  553. ->RenderBool("alive", true)
  554. ->StartObject("friend")
  555. ->RenderString("name", "first")
  556. ->EndObject()
  557. ->StartObject("friend")
  558. ->RenderString("name", "second")
  559. ->EndObject()
  560. ->EndObject()
  561. ->EndObject();
  562. CheckOutput(expected);
  563. }
  564. TEST_P(ProtoStreamObjectWriterTest,
  565. LastWriteWinsOnNonRepeatedMessageFieldWithDuplicates) {
  566. Book expected;
  567. Author* author = expected.mutable_author();
  568. author->set_name("The Author");
  569. Publisher* publisher = expected.mutable_publisher();
  570. publisher->set_name("second");
  571. ow_->StartObject("")
  572. ->StartObject("author")
  573. ->RenderString("name", "The Author")
  574. ->EndObject()
  575. ->StartObject("publisher")
  576. ->RenderString("name", "first")
  577. ->EndObject()
  578. ->StartObject("publisher")
  579. ->RenderString("name", "second")
  580. ->EndObject()
  581. ->EndObject();
  582. CheckOutput(expected);
  583. }
  584. TEST_P(ProtoStreamObjectWriterTest, ExplicitMessageList) {
  585. Book expected;
  586. Author* outer = expected.mutable_author();
  587. outer->set_name("outer");
  588. outer->set_alive(true);
  589. Author* first = outer->add_friend_();
  590. first->set_name("first");
  591. Author* second = outer->add_friend_();
  592. second->set_name("second");
  593. ow_->StartObject("")
  594. ->StartObject("author")
  595. ->RenderString("name", "outer")
  596. ->RenderBool("alive", true)
  597. ->StartList("friend")
  598. ->StartObject("")
  599. ->RenderString("name", "first")
  600. ->EndObject()
  601. ->StartObject("")
  602. ->RenderString("name", "second")
  603. ->EndObject()
  604. ->EndList()
  605. ->EndObject()
  606. ->EndObject();
  607. CheckOutput(expected);
  608. }
  609. TEST_P(ProtoStreamObjectWriterTest, NonRepeatedExplicitMessageList) {
  610. Book expected;
  611. Author* author = expected.mutable_author();
  612. author->set_name("The Author");
  613. EXPECT_CALL(
  614. listener_,
  615. InvalidName(
  616. _, StringPiece("publisher"),
  617. StringPiece("Proto field is not repeating, cannot start list.")))
  618. .With(Args<0>(HasObjectLocation("")));
  619. ow_->StartObject("")
  620. ->StartObject("author")
  621. ->RenderString("name", "The Author")
  622. ->EndObject()
  623. ->StartList("publisher")
  624. ->StartObject("")
  625. ->RenderString("name", "first")
  626. ->EndObject()
  627. ->StartObject("")
  628. ->RenderString("name", "second")
  629. ->EndObject()
  630. ->EndList()
  631. ->EndObject();
  632. CheckOutput(expected);
  633. }
  634. TEST_P(ProtoStreamObjectWriterTest, UnknownFieldAtRoot) {
  635. Book empty;
  636. EXPECT_CALL(listener_, InvalidName(_, StringPiece("unknown"),
  637. StringPiece("Cannot find field.")))
  638. .With(Args<0>(HasObjectLocation("")));
  639. ow_->StartObject("")->RenderString("unknown", "Nope!")->EndObject();
  640. CheckOutput(empty, 0);
  641. }
  642. TEST_P(ProtoStreamObjectWriterTest, UnknownFieldAtAuthorFriend) {
  643. Book expected;
  644. Author* paul = expected.mutable_author();
  645. paul->set_name("Paul");
  646. Author* mark = paul->add_friend_();
  647. mark->set_name("Mark");
  648. Author* john = paul->add_friend_();
  649. john->set_name("John");
  650. Author* luke = paul->add_friend_();
  651. luke->set_name("Luke");
  652. EXPECT_CALL(listener_, InvalidName(_, StringPiece("address"),
  653. StringPiece("Cannot find field.")))
  654. .With(Args<0>(HasObjectLocation("author.friend[1]")));
  655. ow_->StartObject("")
  656. ->StartObject("author")
  657. ->RenderString("name", "Paul")
  658. ->StartList("friend")
  659. ->StartObject("")
  660. ->RenderString("name", "Mark")
  661. ->EndObject()
  662. ->StartObject("")
  663. ->RenderString("name", "John")
  664. ->RenderString("address", "Patmos")
  665. ->EndObject()
  666. ->StartObject("")
  667. ->RenderString("name", "Luke")
  668. ->EndObject()
  669. ->EndList()
  670. ->EndObject()
  671. ->EndObject();
  672. CheckOutput(expected);
  673. }
  674. TEST_P(ProtoStreamObjectWriterTest, UnknownObjectAtRoot) {
  675. Book empty;
  676. EXPECT_CALL(listener_, InvalidName(_, StringPiece("unknown"),
  677. StringPiece("Cannot find field.")))
  678. .With(Args<0>(HasObjectLocation("")));
  679. ow_->StartObject("")->StartObject("unknown")->EndObject()->EndObject();
  680. CheckOutput(empty, 0);
  681. }
  682. TEST_P(ProtoStreamObjectWriterTest, UnknownObjectAtAuthor) {
  683. Book expected;
  684. Author* author = expected.mutable_author();
  685. author->set_name("William");
  686. author->add_pseudonym("Bill");
  687. EXPECT_CALL(listener_, InvalidName(_, StringPiece("wife"),
  688. StringPiece("Cannot find field.")))
  689. .With(Args<0>(HasObjectLocation("author")));
  690. ow_->StartObject("")
  691. ->StartObject("author")
  692. ->RenderString("name", "William")
  693. ->StartObject("wife")
  694. ->RenderString("name", "Hilary")
  695. ->EndObject()
  696. ->RenderString("pseudonym", "Bill")
  697. ->EndObject()
  698. ->EndObject();
  699. CheckOutput(expected);
  700. }
  701. TEST_P(ProtoStreamObjectWriterTest, UnknownListAtRoot) {
  702. Book empty;
  703. EXPECT_CALL(listener_, InvalidName(_, StringPiece("unknown"),
  704. StringPiece("Cannot find field.")))
  705. .With(Args<0>(HasObjectLocation("")));
  706. ow_->StartObject("")->StartList("unknown")->EndList()->EndObject();
  707. CheckOutput(empty, 0);
  708. }
  709. TEST_P(ProtoStreamObjectWriterTest, UnknownListAtPublisher) {
  710. Book expected;
  711. expected.set_title("Brainwashing");
  712. Publisher* publisher = expected.mutable_publisher();
  713. publisher->set_name("propaganda");
  714. EXPECT_CALL(listener_, InvalidName(_, StringPiece("alliance"),
  715. StringPiece("Cannot find field.")))
  716. .With(Args<0>(HasObjectLocation("publisher")));
  717. ow_->StartObject("")
  718. ->StartObject("publisher")
  719. ->RenderString("name", "propaganda")
  720. ->StartList("alliance")
  721. ->EndList()
  722. ->EndObject()
  723. ->RenderString("title", "Brainwashing")
  724. ->EndObject();
  725. CheckOutput(expected);
  726. }
  727. TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownFieldAtRoot) {
  728. Book empty;
  729. options_.ignore_unknown_fields = true;
  730. ResetProtoWriter();
  731. EXPECT_CALL(listener_, InvalidName(_, _, _)).Times(0);
  732. ow_->StartObject("")->RenderString("unknown", "Nope!")->EndObject();
  733. CheckOutput(empty, 0);
  734. }
  735. TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownFieldAtAuthorFriend) {
  736. Book expected;
  737. Author* paul = expected.mutable_author();
  738. paul->set_name("Paul");
  739. Author* mark = paul->add_friend_();
  740. mark->set_name("Mark");
  741. Author* john = paul->add_friend_();
  742. john->set_name("John");
  743. Author* luke = paul->add_friend_();
  744. luke->set_name("Luke");
  745. options_.ignore_unknown_fields = true;
  746. ResetProtoWriter();
  747. EXPECT_CALL(listener_, InvalidName(_, _, _)).Times(0);
  748. ow_->StartObject("")
  749. ->StartObject("author")
  750. ->RenderString("name", "Paul")
  751. ->StartList("friend")
  752. ->StartObject("")
  753. ->RenderString("name", "Mark")
  754. ->EndObject()
  755. ->StartObject("")
  756. ->RenderString("name", "John")
  757. ->RenderString("address", "Patmos")
  758. ->EndObject()
  759. ->StartObject("")
  760. ->RenderString("name", "Luke")
  761. ->EndObject()
  762. ->EndList()
  763. ->EndObject()
  764. ->EndObject();
  765. CheckOutput(expected);
  766. }
  767. TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownObjectAtRoot) {
  768. Book empty;
  769. options_.ignore_unknown_fields = true;
  770. ResetProtoWriter();
  771. EXPECT_CALL(listener_, InvalidName(_, StringPiece("unknown"),
  772. StringPiece("Cannot find field.")))
  773. .Times(0);
  774. ow_->StartObject("")->StartObject("unknown")->EndObject()->EndObject();
  775. CheckOutput(empty, 0);
  776. }
  777. TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownObjectAtAuthor) {
  778. Book expected;
  779. Author* author = expected.mutable_author();
  780. author->set_name("William");
  781. author->add_pseudonym("Bill");
  782. options_.ignore_unknown_fields = true;
  783. ResetProtoWriter();
  784. EXPECT_CALL(listener_, InvalidName(_, _, _)).Times(0);
  785. ow_->StartObject("")
  786. ->StartObject("author")
  787. ->RenderString("name", "William")
  788. ->StartObject("wife")
  789. ->RenderString("name", "Hilary")
  790. ->EndObject()
  791. ->RenderString("pseudonym", "Bill")
  792. ->EndObject()
  793. ->EndObject();
  794. CheckOutput(expected);
  795. }
  796. TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownListAtRoot) {
  797. Book empty;
  798. options_.ignore_unknown_fields = true;
  799. ResetProtoWriter();
  800. EXPECT_CALL(listener_, InvalidName(_, _, _)).Times(0);
  801. ow_->StartObject("")->StartList("unknown")->EndList()->EndObject();
  802. CheckOutput(empty, 0);
  803. }
  804. TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownListAtPublisher) {
  805. Book expected;
  806. expected.set_title("Brainwashing");
  807. Publisher* publisher = expected.mutable_publisher();
  808. publisher->set_name("propaganda");
  809. options_.ignore_unknown_fields = true;
  810. ResetProtoWriter();
  811. EXPECT_CALL(listener_, InvalidName(_, _, _)).Times(0);
  812. ow_->StartObject("")
  813. ->StartObject("publisher")
  814. ->RenderString("name", "propaganda")
  815. ->StartList("alliance")
  816. ->EndList()
  817. ->EndObject()
  818. ->RenderString("title", "Brainwashing")
  819. ->EndObject();
  820. CheckOutput(expected);
  821. }
  822. TEST_P(ProtoStreamObjectWriterTest, AcceptUnknownEnumValue) {
  823. ResetTypeInfo(Proto3Message::descriptor());
  824. Proto3Message expected;
  825. expected.set_enum_value(static_cast<Proto3Message::NestedEnum>(12345));
  826. EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
  827. ow_->StartObject("")
  828. ->RenderInt32("enumValue", 12345)
  829. ->EndObject();
  830. CheckOutput(expected);
  831. }
  832. TEST_P(ProtoStreamObjectWriterTest, MissingRequiredField) {
  833. Book expected;
  834. expected.set_title("My Title");
  835. expected.set_allocated_publisher(new Publisher());
  836. EXPECT_CALL(listener_, MissingField(_, StringPiece("name")))
  837. .With(Args<0>(HasObjectLocation("publisher")));
  838. ow_->StartObject("")
  839. ->StartObject("publisher")
  840. ->EndObject()
  841. ->RenderString("title", "My Title")
  842. ->EndObject();
  843. CheckOutput(expected);
  844. }
  845. TEST_P(ProtoStreamObjectWriterTest, InvalidFieldValueAtRoot) {
  846. Book empty;
  847. EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_UINT32"),
  848. StringPiece("\"garbage\"")))
  849. .With(Args<0>(HasObjectLocation("length")));
  850. ow_->StartObject("")->RenderString("length", "garbage")->EndObject();
  851. CheckOutput(empty, 0);
  852. }
  853. TEST_P(ProtoStreamObjectWriterTest, MultipleInvalidFieldValues) {
  854. Book expected;
  855. expected.set_title("My Title");
  856. EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_UINT32"),
  857. StringPiece("\"-400\"")))
  858. .With(Args<0>(HasObjectLocation("length")));
  859. EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_INT64"),
  860. StringPiece("\"3.14\"")))
  861. .With(Args<0>(HasObjectLocation("published")));
  862. ow_->StartObject("")
  863. ->RenderString("length", "-400")
  864. ->RenderString("published", "3.14")
  865. ->RenderString("title", "My Title")
  866. ->EndObject();
  867. CheckOutput(expected);
  868. }
  869. TEST_P(ProtoStreamObjectWriterTest, UnnamedFieldAtRoot) {
  870. Book empty;
  871. EXPECT_CALL(listener_,
  872. InvalidName(_, StringPiece(""),
  873. StringPiece("Proto fields must have a name.")))
  874. .With(Args<0>(HasObjectLocation("")));
  875. ow_->StartObject("")->RenderFloat("", 3.14)->EndObject();
  876. CheckOutput(empty, 0);
  877. }
  878. TEST_P(ProtoStreamObjectWriterTest, UnnamedFieldAtAuthor) {
  879. Book expected;
  880. expected.set_title("noname");
  881. expected.set_allocated_author(new Author());
  882. EXPECT_CALL(listener_,
  883. InvalidName(_, StringPiece(""),
  884. StringPiece("Proto fields must have a name.")))
  885. .With(Args<0>(HasObjectLocation("author")));
  886. ow_->StartObject("")
  887. ->StartObject("author")
  888. ->RenderInt32("", 123)
  889. ->EndObject()
  890. ->RenderString("title", "noname")
  891. ->EndObject();
  892. CheckOutput(expected);
  893. }
  894. TEST_P(ProtoStreamObjectWriterTest, UnnamedListAtRoot) {
  895. Book expected;
  896. expected.set_title("noname");
  897. EXPECT_CALL(listener_,
  898. InvalidName(_, StringPiece(""),
  899. StringPiece("Proto fields must have a name.")))
  900. .With(Args<0>(HasObjectLocation("")));
  901. ow_->StartObject("")
  902. ->StartList("")
  903. ->EndList()
  904. ->RenderString("title", "noname")
  905. ->EndObject();
  906. CheckOutput(expected);
  907. }
  908. TEST_P(ProtoStreamObjectWriterTest, RootNamedObject) {
  909. Book expected;
  910. expected.set_title("Annie");
  911. EXPECT_CALL(listener_,
  912. InvalidName(_, StringPiece("oops"),
  913. StringPiece("Root element should not be named.")))
  914. .With(Args<0>(HasObjectLocation("")));
  915. ow_->StartObject("oops")->RenderString("title", "Annie")->EndObject();
  916. CheckOutput(expected, 7);
  917. }
  918. TEST_P(ProtoStreamObjectWriterTest, RootNamedList) {
  919. Book empty;
  920. EXPECT_CALL(listener_,
  921. InvalidName(_, StringPiece("oops"),
  922. StringPiece("Root element should not be named.")))
  923. .With(Args<0>(HasObjectLocation("")));
  924. ow_->StartList("oops")->RenderString("", "item")->EndList();
  925. CheckOutput(empty, 0);
  926. }
  927. TEST_P(ProtoStreamObjectWriterTest, RootUnnamedField) {
  928. Book empty;
  929. EXPECT_CALL(listener_,
  930. InvalidName(_, StringPiece(""),
  931. StringPiece("Root element must be a message.")))
  932. .With(Args<0>(HasObjectLocation("")));
  933. ow_->RenderBool("", true);
  934. CheckOutput(empty, 0);
  935. }
  936. TEST_P(ProtoStreamObjectWriterTest, RootNamedField) {
  937. Book empty;
  938. EXPECT_CALL(listener_,
  939. InvalidName(_, StringPiece("oops"),
  940. StringPiece("Root element must be a message.")))
  941. .With(Args<0>(HasObjectLocation("")));
  942. ow_->RenderBool("oops", true);
  943. CheckOutput(empty, 0);
  944. }
  945. TEST_P(ProtoStreamObjectWriterTest, NullValue) {
  946. Book empty;
  947. ow_->RenderNull("");
  948. CheckOutput(empty, 0);
  949. }
  950. TEST_P(ProtoStreamObjectWriterTest, NullValueForMessageField) {
  951. Book empty;
  952. ow_->RenderNull("author");
  953. CheckOutput(empty, 0);
  954. }
  955. TEST_P(ProtoStreamObjectWriterTest, NullValueForPrimitiveField) {
  956. Book empty;
  957. ow_->RenderNull("length");
  958. CheckOutput(empty, 0);
  959. }
  960. class ProtoStreamObjectWriterTimestampDurationTest
  961. : public BaseProtoStreamObjectWriterTest {
  962. protected:
  963. ProtoStreamObjectWriterTimestampDurationTest() {
  964. std::vector<const Descriptor*> descriptors;
  965. descriptors.push_back(TimestampDuration::descriptor());
  966. descriptors.push_back(google::protobuf::Timestamp::descriptor());
  967. descriptors.push_back(google::protobuf::Duration::descriptor());
  968. ResetTypeInfo(descriptors);
  969. }
  970. };
  971. INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
  972. ProtoStreamObjectWriterTimestampDurationTest,
  973. ::testing::Values(
  974. testing::USE_TYPE_RESOLVER));
  975. TEST_P(ProtoStreamObjectWriterTimestampDurationTest, ParseTimestamp) {
  976. TimestampDuration timestamp;
  977. google::protobuf::Timestamp* ts = timestamp.mutable_ts();
  978. ts->set_seconds(1448249855);
  979. ts->set_nanos(33155000);
  980. ow_->StartObject("")
  981. ->RenderString("ts", "2015-11-23T03:37:35.033155Z")
  982. ->EndObject();
  983. CheckOutput(timestamp);
  984. }
  985. TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
  986. ParseTimestampYearNotZeroPadded) {
  987. TimestampDuration timestamp;
  988. google::protobuf::Timestamp* ts = timestamp.mutable_ts();
  989. ts->set_seconds(-61665654145);
  990. ts->set_nanos(33155000);
  991. ow_->StartObject("")
  992. ->RenderString("ts", "15-11-23T03:37:35.033155Z")
  993. ->EndObject();
  994. CheckOutput(timestamp);
  995. }
  996. TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
  997. ParseTimestampYearZeroPadded) {
  998. TimestampDuration timestamp;
  999. google::protobuf::Timestamp* ts = timestamp.mutable_ts();
  1000. ts->set_seconds(-61665654145);
  1001. ts->set_nanos(33155000);
  1002. ow_->StartObject("")
  1003. ->RenderString("ts", "0015-11-23T03:37:35.033155Z")
  1004. ->EndObject();
  1005. CheckOutput(timestamp);
  1006. }
  1007. TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
  1008. ParseTimestampWithPositiveOffset) {
  1009. TimestampDuration timestamp;
  1010. google::protobuf::Timestamp* ts = timestamp.mutable_ts();
  1011. ts->set_seconds(1448249855);
  1012. ts->set_nanos(33155000);
  1013. ow_->StartObject("")
  1014. ->RenderString("ts", "2015-11-23T11:47:35.033155+08:10")
  1015. ->EndObject();
  1016. CheckOutput(timestamp);
  1017. }
  1018. TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
  1019. ParseTimestampWithNegativeOffset) {
  1020. TimestampDuration timestamp;
  1021. google::protobuf::Timestamp* ts = timestamp.mutable_ts();
  1022. ts->set_seconds(1448249855);
  1023. ts->set_nanos(33155000);
  1024. ow_->StartObject("")
  1025. ->RenderString("ts", "2015-11-22T19:47:35.033155-07:50")
  1026. ->EndObject();
  1027. CheckOutput(timestamp);
  1028. }
  1029. TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
  1030. TimestampWithInvalidOffset1) {
  1031. TimestampDuration timestamp;
  1032. EXPECT_CALL(
  1033. listener_,
  1034. InvalidValue(_,
  1035. StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
  1036. StringPiece("Field 'ts', Invalid time format: "
  1037. "2016-03-07T15:14:23+")));
  1038. ow_->StartObject("")->RenderString("ts", "2016-03-07T15:14:23+")->EndObject();
  1039. CheckOutput(timestamp);
  1040. }
  1041. TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
  1042. TimestampWithInvalidOffset2) {
  1043. TimestampDuration timestamp;
  1044. EXPECT_CALL(
  1045. listener_,
  1046. InvalidValue(_,
  1047. StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
  1048. StringPiece("Field 'ts', Invalid time format: "
  1049. "2016-03-07T15:14:23+08-10")));
  1050. ow_->StartObject("")
  1051. ->RenderString("ts", "2016-03-07T15:14:23+08-10")
  1052. ->EndObject();
  1053. CheckOutput(timestamp);
  1054. }
  1055. TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
  1056. TimestampWithInvalidOffset3) {
  1057. TimestampDuration timestamp;
  1058. EXPECT_CALL(
  1059. listener_,
  1060. InvalidValue(_,
  1061. StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
  1062. StringPiece("Field 'ts', Invalid time format: "
  1063. "2016-03-07T15:14:23+24:10")));
  1064. ow_->StartObject("")
  1065. ->RenderString("ts", "2016-03-07T15:14:23+24:10")
  1066. ->EndObject();
  1067. CheckOutput(timestamp);
  1068. }
  1069. TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
  1070. TimestampWithInvalidOffset4) {
  1071. TimestampDuration timestamp;
  1072. EXPECT_CALL(
  1073. listener_,
  1074. InvalidValue(_,
  1075. StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
  1076. StringPiece("Field 'ts', Invalid time format: "
  1077. "2016-03-07T15:14:23+04:60")));
  1078. ow_->StartObject("")
  1079. ->RenderString("ts", "2016-03-07T15:14:23+04:60")
  1080. ->EndObject();
  1081. CheckOutput(timestamp);
  1082. }
  1083. TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError1) {
  1084. TimestampDuration timestamp;
  1085. EXPECT_CALL(
  1086. listener_,
  1087. InvalidValue(_,
  1088. StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
  1089. StringPiece("Field 'ts', Invalid time format: ")));
  1090. ow_->StartObject("")->RenderString("ts", "")->EndObject();
  1091. CheckOutput(timestamp);
  1092. }
  1093. TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError2) {
  1094. TimestampDuration timestamp;
  1095. EXPECT_CALL(
  1096. listener_,
  1097. InvalidValue(_,
  1098. StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
  1099. StringPiece("Field 'ts', Invalid time format: Z")));
  1100. ow_->StartObject("")->RenderString("ts", "Z")->EndObject();
  1101. CheckOutput(timestamp);
  1102. }
  1103. TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError3) {
  1104. TimestampDuration timestamp;
  1105. EXPECT_CALL(
  1106. listener_,
  1107. InvalidValue(_,
  1108. StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
  1109. StringPiece("Field 'ts', Invalid time format: "
  1110. "1970-01-01T00:00:00.ABZ")));
  1111. ow_->StartObject("")
  1112. ->RenderString("ts", "1970-01-01T00:00:00.ABZ")
  1113. ->EndObject();
  1114. CheckOutput(timestamp);
  1115. }
  1116. TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError4) {
  1117. TimestampDuration timestamp;
  1118. EXPECT_CALL(
  1119. listener_,
  1120. InvalidValue(_,
  1121. StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
  1122. StringPiece("Field 'ts', Invalid time format: "
  1123. "-8031-10-18T00:00:00.000Z")));
  1124. ow_->StartObject("")
  1125. ->RenderString("ts", "-8031-10-18T00:00:00.000Z")
  1126. ->EndObject();
  1127. CheckOutput(timestamp);
  1128. }
  1129. TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError5) {
  1130. TimestampDuration timestamp;
  1131. EXPECT_CALL(
  1132. listener_,
  1133. InvalidValue(_,
  1134. StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
  1135. StringPiece("Field 'ts', Invalid time format: "
  1136. "2015-11-23T03:37:35.033155 Z")));
  1137. ow_->StartObject("")
  1138. // Whitespace in the Timestamp nanos is not allowed.
  1139. ->RenderString("ts", "2015-11-23T03:37:35.033155 Z")
  1140. ->EndObject();
  1141. CheckOutput(timestamp);
  1142. }
  1143. TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError6) {
  1144. TimestampDuration timestamp;
  1145. EXPECT_CALL(
  1146. listener_,
  1147. InvalidValue(_,
  1148. StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
  1149. StringPiece("Field 'ts', Invalid time format: "
  1150. "2015-11-23T03:37:35.033155 1234Z")));
  1151. ow_->StartObject("")
  1152. // Whitespace in the Timestamp nanos is not allowed.
  1153. ->RenderString("ts", "2015-11-23T03:37:35.033155 1234Z")
  1154. ->EndObject();
  1155. CheckOutput(timestamp);
  1156. }
  1157. TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError7) {
  1158. TimestampDuration timestamp;
  1159. EXPECT_CALL(
  1160. listener_,
  1161. InvalidValue(_,
  1162. StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
  1163. StringPiece("Field 'ts', Invalid time format: "
  1164. "2015-11-23T03:37:35.033abc155Z")));
  1165. ow_->StartObject("")
  1166. // Non-numeric characters in the Timestamp nanos is not allowed.
  1167. ->RenderString("ts", "2015-11-23T03:37:35.033abc155Z")
  1168. ->EndObject();
  1169. CheckOutput(timestamp);
  1170. }
  1171. TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError8) {
  1172. TimestampDuration timestamp;
  1173. EXPECT_CALL(
  1174. listener_,
  1175. InvalidValue(_,
  1176. StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
  1177. StringPiece("Field 'ts', Invalid time format: "
  1178. "0-12-31T23:59:59.000Z")));
  1179. ow_->StartObject("")
  1180. ->RenderString("ts", "0-12-31T23:59:59.000Z")
  1181. ->EndObject();
  1182. CheckOutput(timestamp);
  1183. }
  1184. TEST_P(ProtoStreamObjectWriterTimestampDurationTest, ParseDuration) {
  1185. TimestampDuration duration;
  1186. google::protobuf::Duration* dur = duration.mutable_dur();
  1187. dur->set_seconds(1448216930);
  1188. dur->set_nanos(132262000);
  1189. ow_->StartObject("")->RenderString("dur", "1448216930.132262s")->EndObject();
  1190. CheckOutput(duration);
  1191. }
  1192. TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidDurationError1) {
  1193. TimestampDuration duration;
  1194. EXPECT_CALL(
  1195. listener_,
  1196. InvalidValue(
  1197. _, StringPiece("type.googleapis.com/google.protobuf.Duration"),
  1198. StringPiece("Field 'dur', Illegal duration format; duration must "
  1199. "end with 's'")));
  1200. ow_->StartObject("")->RenderString("dur", "")->EndObject();
  1201. CheckOutput(duration);
  1202. }
  1203. TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidDurationError2) {
  1204. TimestampDuration duration;
  1205. EXPECT_CALL(
  1206. listener_,
  1207. InvalidValue(
  1208. _, StringPiece("type.googleapis.com/google.protobuf.Duration"),
  1209. StringPiece("Field 'dur', Invalid duration format, failed to parse "
  1210. "seconds")));
  1211. ow_->StartObject("")->RenderString("dur", "s")->EndObject();
  1212. CheckOutput(duration);
  1213. }
  1214. TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidDurationError3) {
  1215. TimestampDuration duration;
  1216. EXPECT_CALL(
  1217. listener_,
  1218. InvalidValue(
  1219. _, StringPiece("type.googleapis.com/google.protobuf.Duration"),
  1220. StringPiece("Field 'dur', Invalid duration format, failed to "
  1221. "parse nano seconds")));
  1222. ow_->StartObject("")->RenderString("dur", "123.DEFs")->EndObject();
  1223. CheckOutput(duration);
  1224. }
  1225. TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidDurationError4) {
  1226. TimestampDuration duration;
  1227. EXPECT_CALL(
  1228. listener_,
  1229. InvalidValue(_,
  1230. StringPiece("type.googleapis.com/google.protobuf.Duration"),
  1231. StringPiece("Field 'dur', Duration value exceeds limits")));
  1232. ow_->StartObject("")->RenderString("dur", "315576000002s")->EndObject();
  1233. CheckOutput(duration);
  1234. }
  1235. TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidDurationError5) {
  1236. TimestampDuration duration;
  1237. EXPECT_CALL(
  1238. listener_,
  1239. InvalidValue(_,
  1240. StringPiece("type.googleapis.com/google.protobuf.Duration"),
  1241. StringPiece("Field 'dur', Duration value exceeds limits")));
  1242. ow_->StartObject("")->RenderString("dur", "0.1000000001s")->EndObject();
  1243. CheckOutput(duration);
  1244. }
  1245. TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
  1246. MismatchedTimestampTypeInput) {
  1247. TimestampDuration timestamp;
  1248. EXPECT_CALL(
  1249. listener_,
  1250. InvalidValue(
  1251. _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
  1252. StringPiece(
  1253. "Field 'ts', Invalid data type for timestamp, value is 1")))
  1254. .With(Args<0>(HasObjectLocation("ts")));
  1255. ow_->StartObject("")->RenderInt32("ts", 1)->EndObject();
  1256. CheckOutput(timestamp);
  1257. }
  1258. TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
  1259. MismatchedDurationTypeInput) {
  1260. TimestampDuration duration;
  1261. EXPECT_CALL(
  1262. listener_,
  1263. InvalidValue(
  1264. _, StringPiece("type.googleapis.com/google.protobuf.Duration"),
  1265. StringPiece(
  1266. "Field 'dur', Invalid data type for duration, value is 1")))
  1267. .With(Args<0>(HasObjectLocation("dur")));
  1268. ow_->StartObject("")->RenderInt32("dur", 1)->EndObject();
  1269. CheckOutput(duration);
  1270. }
  1271. TEST_P(ProtoStreamObjectWriterTimestampDurationTest, TimestampAcceptsNull) {
  1272. TimestampDuration timestamp;
  1273. EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
  1274. ow_->StartObject("")->RenderNull("ts")->EndObject();
  1275. CheckOutput(timestamp);
  1276. }
  1277. TEST_P(ProtoStreamObjectWriterTimestampDurationTest, DurationAcceptsNull) {
  1278. TimestampDuration duration;
  1279. EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
  1280. ow_->StartObject("")->RenderNull("dur")->EndObject();
  1281. CheckOutput(duration);
  1282. }
  1283. class ProtoStreamObjectWriterStructTest
  1284. : public BaseProtoStreamObjectWriterTest {
  1285. protected:
  1286. ProtoStreamObjectWriterStructTest() { ResetProtoWriter(); }
  1287. // Resets ProtoWriter with current set of options and other state.
  1288. void ResetProtoWriter() {
  1289. std::vector<const Descriptor*> descriptors;
  1290. descriptors.push_back(StructType::descriptor());
  1291. descriptors.push_back(google::protobuf::Struct::descriptor());
  1292. ResetTypeInfo(descriptors);
  1293. }
  1294. };
  1295. INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
  1296. ProtoStreamObjectWriterStructTest,
  1297. ::testing::Values(
  1298. testing::USE_TYPE_RESOLVER));
  1299. // TODO(skarvaje): Write tests for failure cases.
  1300. TEST_P(ProtoStreamObjectWriterStructTest, StructRenderSuccess) {
  1301. StructType struct_type;
  1302. google::protobuf::Struct* s = struct_type.mutable_object();
  1303. s->mutable_fields()->operator[]("k1").set_number_value(123);
  1304. s->mutable_fields()->operator[]("k2").set_bool_value(true);
  1305. ow_->StartObject("")
  1306. ->StartObject("object")
  1307. ->RenderDouble("k1", 123)
  1308. ->RenderBool("k2", true)
  1309. ->EndObject()
  1310. ->EndObject();
  1311. CheckOutput(struct_type);
  1312. }
  1313. TEST_P(ProtoStreamObjectWriterStructTest, StructNullInputSuccess) {
  1314. StructType struct_type;
  1315. EXPECT_CALL(listener_,
  1316. InvalidName(_, StringPiece(""),
  1317. StringPiece("Proto fields must have a name.")))
  1318. .With(Args<0>(HasObjectLocation("")));
  1319. ow_->StartObject("")->RenderNull("")->EndObject();
  1320. CheckOutput(struct_type);
  1321. }
  1322. TEST_P(ProtoStreamObjectWriterStructTest, StructInvalidInputFailure) {
  1323. StructType struct_type;
  1324. EXPECT_CALL(
  1325. listener_,
  1326. InvalidValue(_, StringPiece("type.googleapis.com/google.protobuf.Struct"),
  1327. StringPiece("true")))
  1328. .With(Args<0>(HasObjectLocation("object")));
  1329. ow_->StartObject("")->RenderBool("object", true)->EndObject();
  1330. CheckOutput(struct_type);
  1331. }
  1332. TEST_P(ProtoStreamObjectWriterStructTest, StructAcceptsNull) {
  1333. StructType struct_type;
  1334. EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
  1335. ow_->StartObject("")->RenderNull("object")->EndObject();
  1336. CheckOutput(struct_type);
  1337. }
  1338. TEST_P(ProtoStreamObjectWriterStructTest, StructValuePreservesNull) {
  1339. StructType struct_type;
  1340. (*struct_type.mutable_object()->mutable_fields())["key"].set_null_value(
  1341. google::protobuf::NULL_VALUE);
  1342. EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
  1343. ow_->StartObject("")
  1344. ->StartObject("object")
  1345. ->RenderNull("key")
  1346. ->EndObject()
  1347. ->EndObject();
  1348. CheckOutput(struct_type);
  1349. }
  1350. TEST_P(ProtoStreamObjectWriterStructTest, SimpleRepeatedStructMapKeyTest) {
  1351. EXPECT_CALL(
  1352. listener_,
  1353. InvalidName(_, StringPiece("gBike"),
  1354. StringPiece("Repeated map key: 'gBike' is already set.")));
  1355. ow_->StartObject("")
  1356. ->StartObject("object")
  1357. ->RenderString("gBike", "v1")
  1358. ->RenderString("gBike", "v2")
  1359. ->EndObject()
  1360. ->EndObject();
  1361. }
  1362. TEST_P(ProtoStreamObjectWriterStructTest, RepeatedStructMapListKeyTest) {
  1363. EXPECT_CALL(
  1364. listener_,
  1365. InvalidName(_, StringPiece("k1"),
  1366. StringPiece("Repeated map key: 'k1' is already set.")));
  1367. ow_->StartObject("")
  1368. ->StartObject("object")
  1369. ->RenderString("k1", "v1")
  1370. ->StartList("k1")
  1371. ->RenderString("", "v2")
  1372. ->EndList()
  1373. ->EndObject()
  1374. ->EndObject();
  1375. }
  1376. TEST_P(ProtoStreamObjectWriterStructTest, RepeatedStructMapObjectKeyTest) {
  1377. EXPECT_CALL(
  1378. listener_,
  1379. InvalidName(_, StringPiece("k1"),
  1380. StringPiece("Repeated map key: 'k1' is already set.")));
  1381. ow_->StartObject("")
  1382. ->StartObject("object")
  1383. ->StartObject("k1")
  1384. ->RenderString("sub_k1", "v1")
  1385. ->EndObject()
  1386. ->StartObject("k1")
  1387. ->RenderString("sub_k2", "v2")
  1388. ->EndObject()
  1389. ->EndObject()
  1390. ->EndObject();
  1391. }
  1392. TEST_P(ProtoStreamObjectWriterStructTest, OptionStructIntAsStringsTest) {
  1393. StructType struct_type;
  1394. google::protobuf::Struct* s = struct_type.mutable_object();
  1395. s->mutable_fields()->operator[]("k1").set_string_value("123");
  1396. s->mutable_fields()->operator[]("k2").set_bool_value(true);
  1397. s->mutable_fields()->operator[]("k3").set_string_value("-222222222");
  1398. s->mutable_fields()->operator[]("k4").set_string_value("33333333");
  1399. options_.struct_integers_as_strings = true;
  1400. ResetProtoWriter();
  1401. ow_->StartObject("")
  1402. ->StartObject("object")
  1403. ->RenderDouble("k1", 123)
  1404. ->RenderBool("k2", true)
  1405. ->RenderInt64("k3", -222222222)
  1406. ->RenderUint64("k4", 33333333)
  1407. ->EndObject()
  1408. ->EndObject();
  1409. CheckOutput(struct_type);
  1410. }
  1411. TEST_P(ProtoStreamObjectWriterStructTest, ValuePreservesNull) {
  1412. ValueWrapper value;
  1413. value.mutable_value()->set_null_value(google::protobuf::NULL_VALUE);
  1414. EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
  1415. ow_->StartObject("")->RenderNull("value")->EndObject();
  1416. CheckOutput(value);
  1417. }
  1418. class ProtoStreamObjectWriterMapTest : public BaseProtoStreamObjectWriterTest {
  1419. protected:
  1420. ProtoStreamObjectWriterMapTest()
  1421. : BaseProtoStreamObjectWriterTest(MapIn::descriptor()) {}
  1422. };
  1423. INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
  1424. ProtoStreamObjectWriterMapTest,
  1425. ::testing::Values(
  1426. testing::USE_TYPE_RESOLVER));
  1427. TEST_P(ProtoStreamObjectWriterMapTest, MapShouldNotAcceptList) {
  1428. MapIn mm;
  1429. EXPECT_CALL(
  1430. listener_,
  1431. InvalidValue(
  1432. _, StringPiece("Map"),
  1433. StringPiece("Cannot bind a list to map for field 'map_input'.")));
  1434. ow_->StartObject("")
  1435. ->StartList("map_input")
  1436. ->RenderString("a", "b")
  1437. ->EndList()
  1438. ->EndObject();
  1439. CheckOutput(mm);
  1440. }
  1441. TEST_P(ProtoStreamObjectWriterMapTest, RepeatedMapKeyTest) {
  1442. EXPECT_CALL(
  1443. listener_,
  1444. InvalidName(_, StringPiece("k1"),
  1445. StringPiece("Repeated map key: 'k1' is already set.")));
  1446. ow_->StartObject("")
  1447. ->RenderString("other", "test")
  1448. ->StartObject("map_input")
  1449. ->RenderString("k1", "v1")
  1450. ->RenderString("k1", "v2")
  1451. ->EndObject()
  1452. ->EndObject();
  1453. }
  1454. class ProtoStreamObjectWriterAnyTest : public BaseProtoStreamObjectWriterTest {
  1455. protected:
  1456. ProtoStreamObjectWriterAnyTest() {
  1457. std::vector<const Descriptor*> descriptors;
  1458. descriptors.push_back(AnyOut::descriptor());
  1459. descriptors.push_back(Book::descriptor());
  1460. descriptors.push_back(google::protobuf::Any::descriptor());
  1461. descriptors.push_back(google::protobuf::DoubleValue::descriptor());
  1462. descriptors.push_back(google::protobuf::FieldMask::descriptor());
  1463. descriptors.push_back(google::protobuf::Int32Value::descriptor());
  1464. descriptors.push_back(google::protobuf::Struct::descriptor());
  1465. descriptors.push_back(google::protobuf::Timestamp::descriptor());
  1466. descriptors.push_back(google::protobuf::Value::descriptor());
  1467. ResetTypeInfo(descriptors);
  1468. }
  1469. };
  1470. INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
  1471. ProtoStreamObjectWriterAnyTest,
  1472. ::testing::Values(
  1473. testing::USE_TYPE_RESOLVER));
  1474. TEST_P(ProtoStreamObjectWriterAnyTest, AnyRenderSuccess) {
  1475. AnyOut any;
  1476. google::protobuf::Any* any_type = any.mutable_any();
  1477. any_type->set_type_url("type.googleapis.com/google.protobuf.DoubleValue");
  1478. google::protobuf::DoubleValue d;
  1479. d.set_value(40.2);
  1480. any_type->set_value(d.SerializeAsString());
  1481. ow_->StartObject("")
  1482. ->StartObject("any")
  1483. ->RenderString("@type", "type.googleapis.com/google.protobuf.DoubleValue")
  1484. ->RenderDouble("value", 40.2)
  1485. ->EndObject()
  1486. ->EndObject();
  1487. CheckOutput(any);
  1488. }
  1489. TEST_P(ProtoStreamObjectWriterAnyTest, RecursiveAny) {
  1490. AnyOut out;
  1491. ::google::protobuf::Any* any = out.mutable_any();
  1492. any->set_type_url("type.googleapis.com/google.protobuf.Any");
  1493. ::google::protobuf::Any nested_any;
  1494. nested_any.set_type_url("type.googleapis.com/google.protobuf.testing.AnyM");
  1495. AnyM m;
  1496. m.set_foo("foovalue");
  1497. nested_any.set_value(m.SerializeAsString());
  1498. any->set_value(nested_any.SerializeAsString());
  1499. ow_->StartObject("")
  1500. ->StartObject("any")
  1501. ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
  1502. ->StartObject("value")
  1503. ->RenderString("@type",
  1504. "type.googleapis.com/google.protobuf.testing.AnyM")
  1505. ->RenderString("foo", "foovalue")
  1506. ->EndObject()
  1507. ->EndObject()
  1508. ->EndObject();
  1509. CheckOutput(out, 107);
  1510. }
  1511. TEST_P(ProtoStreamObjectWriterAnyTest, DoubleRecursiveAny) {
  1512. AnyOut out;
  1513. ::google::protobuf::Any* any = out.mutable_any();
  1514. any->set_type_url("type.googleapis.com/google.protobuf.Any");
  1515. ::google::protobuf::Any nested_any;
  1516. nested_any.set_type_url("type.googleapis.com/google.protobuf.Any");
  1517. ::google::protobuf::Any second_nested_any;
  1518. second_nested_any.set_type_url(
  1519. "type.googleapis.com/google.protobuf.testing.AnyM");
  1520. AnyM m;
  1521. m.set_foo("foovalue");
  1522. second_nested_any.set_value(m.SerializeAsString());
  1523. nested_any.set_value(second_nested_any.SerializeAsString());
  1524. any->set_value(nested_any.SerializeAsString());
  1525. ow_->StartObject("")
  1526. ->StartObject("any")
  1527. ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
  1528. ->StartObject("value")
  1529. ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
  1530. ->StartObject("value")
  1531. ->RenderString("@type",
  1532. "type.googleapis.com/google.protobuf.testing.AnyM")
  1533. ->RenderString("foo", "foovalue")
  1534. ->EndObject()
  1535. ->EndObject()
  1536. ->EndObject()
  1537. ->EndObject();
  1538. CheckOutput(out, 151);
  1539. }
  1540. TEST_P(ProtoStreamObjectWriterAnyTest, TypeUrlAtEnd) {
  1541. Book book;
  1542. book.set_title("C++");
  1543. book.set_length(1234);
  1544. book.set_content("Hello World!");
  1545. ::google::protobuf::Any any;
  1546. any.PackFrom(book);
  1547. ::google::protobuf::Any outer_any;
  1548. outer_any.PackFrom(any);
  1549. AnyOut out;
  1550. out.mutable_any()->PackFrom(outer_any);
  1551. // Put the @type field at the end of each Any message. Parsers should
  1552. // be able to accept that.
  1553. ow_->StartObject("")
  1554. ->StartObject("any")
  1555. ->StartObject("value")
  1556. ->StartObject("value")
  1557. ->RenderString("title", "C++")
  1558. ->RenderInt32("length", 1234)
  1559. ->RenderBytes("content", "Hello World!")
  1560. ->RenderString("@type",
  1561. "type.googleapis.com/google.protobuf.testing.Book")
  1562. ->EndObject()
  1563. ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
  1564. ->EndObject()
  1565. ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
  1566. ->EndObject()
  1567. ->EndObject();
  1568. CheckOutput(out);
  1569. }
  1570. // Same as TypeUrlAtEnd, but use temporary string values to make sure we don't
  1571. // mistakenly store StringPiece objects pointing to invalid memory.
  1572. TEST_P(ProtoStreamObjectWriterAnyTest, TypeUrlAtEndWithTemporaryStrings) {
  1573. Book book;
  1574. book.set_title("C++");
  1575. book.set_length(1234);
  1576. book.set_content("Hello World!");
  1577. ::google::protobuf::Any any;
  1578. any.PackFrom(book);
  1579. ::google::protobuf::Any outer_any;
  1580. outer_any.PackFrom(any);
  1581. AnyOut out;
  1582. out.mutable_any()->PackFrom(outer_any);
  1583. string name, value;
  1584. // Put the @type field at the end of each Any message. Parsers should
  1585. // be able to accept that.
  1586. ow_->StartObject("")->StartObject("any");
  1587. {
  1588. ow_->StartObject("value");
  1589. {
  1590. ow_->StartObject("value");
  1591. {
  1592. name = "title";
  1593. value = "C++";
  1594. ow_->RenderString(name, value);
  1595. name = "length";
  1596. ow_->RenderInt32(name, 1234);
  1597. name = "content";
  1598. value = "Hello World!";
  1599. ow_->RenderBytes(name, value);
  1600. name = "@type";
  1601. value = "type.googleapis.com/google.protobuf.testing.Book";
  1602. ow_->RenderString(name, value);
  1603. }
  1604. ow_->EndObject();
  1605. name = "@type";
  1606. value = "type.googleapis.com/google.protobuf.Any";
  1607. ow_->RenderString(name, value);
  1608. }
  1609. ow_->EndObject();
  1610. name = "@type";
  1611. value = "type.googleapis.com/google.protobuf.Any";
  1612. ow_->RenderString(name, value);
  1613. }
  1614. ow_->EndObject()->EndObject();
  1615. CheckOutput(out);
  1616. }
  1617. TEST_P(ProtoStreamObjectWriterAnyTest, EmptyAnyFromEmptyObject) {
  1618. AnyOut out;
  1619. out.mutable_any();
  1620. EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
  1621. ow_->StartObject("")->StartObject("any")->EndObject()->EndObject();
  1622. CheckOutput(out, 2);
  1623. }
  1624. TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithoutTypeUrlFails1) {
  1625. AnyOut any;
  1626. EXPECT_CALL(listener_,
  1627. InvalidValue(_, StringPiece("Any"),
  1628. StringPiece("Missing @type for any field in "
  1629. "google.protobuf.testing.AnyOut")));
  1630. ow_->StartObject("")
  1631. ->StartObject("any")
  1632. ->StartObject("another")
  1633. ->EndObject()
  1634. ->EndObject()
  1635. ->EndObject();
  1636. CheckOutput(any);
  1637. }
  1638. TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithoutTypeUrlFails2) {
  1639. AnyOut any;
  1640. EXPECT_CALL(listener_,
  1641. InvalidValue(_, StringPiece("Any"),
  1642. StringPiece("Missing @type for any field in "
  1643. "google.protobuf.testing.AnyOut")));
  1644. ow_->StartObject("")
  1645. ->StartObject("any")
  1646. ->StartList("another")
  1647. ->EndObject()
  1648. ->EndObject()
  1649. ->EndObject();
  1650. CheckOutput(any);
  1651. }
  1652. TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithoutTypeUrlFails3) {
  1653. AnyOut any;
  1654. EXPECT_CALL(listener_,
  1655. InvalidValue(_, StringPiece("Any"),
  1656. StringPiece("Missing @type for any field in "
  1657. "google.protobuf.testing.AnyOut")));
  1658. ow_->StartObject("")
  1659. ->StartObject("any")
  1660. ->RenderString("value", "somevalue")
  1661. ->EndObject()
  1662. ->EndObject();
  1663. CheckOutput(any);
  1664. }
  1665. TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithInvalidTypeUrlFails) {
  1666. AnyOut any;
  1667. EXPECT_CALL(listener_,
  1668. InvalidValue(
  1669. _, StringPiece("Any"),
  1670. StringPiece("Invalid type URL, type URLs must be of the form "
  1671. "'type.googleapis.com/<typename>', got: "
  1672. "type.other.com/some.Type")));
  1673. ow_->StartObject("")
  1674. ->StartObject("any")
  1675. ->RenderString("@type", "type.other.com/some.Type")
  1676. ->RenderDouble("value", 40.2)
  1677. ->EndObject()
  1678. ->EndObject();
  1679. CheckOutput(any);
  1680. }
  1681. TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithUnknownTypeFails) {
  1682. AnyOut any;
  1683. EXPECT_CALL(
  1684. listener_,
  1685. InvalidValue(_, StringPiece("Any"),
  1686. StringPiece("Invalid type URL, unknown type: some.Type")));
  1687. ow_->StartObject("")
  1688. ->StartObject("any")
  1689. ->RenderString("@type", "type.googleapis.com/some.Type")
  1690. ->RenderDouble("value", 40.2)
  1691. ->EndObject()
  1692. ->EndObject();
  1693. CheckOutput(any);
  1694. }
  1695. TEST_P(ProtoStreamObjectWriterAnyTest, AnyIncorrectInputTypeFails) {
  1696. AnyOut any;
  1697. EXPECT_CALL(
  1698. listener_,
  1699. InvalidValue(_, StringPiece("type.googleapis.com/google.protobuf.Any"),
  1700. StringPiece("1")));
  1701. ow_->StartObject("")->RenderInt32("any", 1)->EndObject();
  1702. CheckOutput(any);
  1703. }
  1704. TEST_P(ProtoStreamObjectWriterAnyTest, AnyAcceptsNull) {
  1705. AnyOut any;
  1706. EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
  1707. ow_->StartObject("")->RenderNull("any")->EndObject();
  1708. CheckOutput(any);
  1709. }
  1710. TEST_P(ProtoStreamObjectWriterAnyTest, AnyWellKnownTypeErrorTest) {
  1711. EXPECT_CALL(listener_, InvalidValue(_, StringPiece("Any"),
  1712. StringPiece("Invalid time format: ")));
  1713. AnyOut any;
  1714. google::protobuf::Any* any_type = any.mutable_any();
  1715. any_type->set_type_url("type.googleapis.com/google.protobuf.Timestamp");
  1716. ow_->StartObject("")
  1717. ->StartObject("any")
  1718. ->RenderString("@type", "type.googleapis.com/google.protobuf.Timestamp")
  1719. ->RenderString("value", "")
  1720. ->EndObject()
  1721. ->EndObject();
  1722. CheckOutput(any);
  1723. }
  1724. // Test the following case:
  1725. //
  1726. // {
  1727. // "any": {
  1728. // "@type": "type.googleapis.com/google.protobuf.Value",
  1729. // "value": "abc"
  1730. // }
  1731. // }
  1732. TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithNestedPrimitiveValue) {
  1733. AnyOut out;
  1734. ::google::protobuf::Any* any = out.mutable_any();
  1735. ::google::protobuf::Value value;
  1736. value.set_string_value("abc");
  1737. any->PackFrom(value);
  1738. ow_->StartObject("")
  1739. ->StartObject("any")
  1740. ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
  1741. ->RenderString("value", "abc")
  1742. ->EndObject()
  1743. ->EndObject();
  1744. CheckOutput(out);
  1745. }
  1746. // Test the following case:
  1747. //
  1748. // {
  1749. // "any": {
  1750. // "@type": "type.googleapis.com/google.protobuf.Value",
  1751. // "value": {
  1752. // "foo": "abc"
  1753. // }
  1754. // }
  1755. // }
  1756. TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithNestedObjectValue) {
  1757. AnyOut out;
  1758. ::google::protobuf::Any* any = out.mutable_any();
  1759. ::google::protobuf::Value value;
  1760. (*value.mutable_struct_value()->mutable_fields())["foo"].set_string_value(
  1761. "abc");
  1762. any->PackFrom(value);
  1763. ow_->StartObject("")
  1764. ->StartObject("any")
  1765. ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
  1766. ->StartObject("value")
  1767. ->RenderString("foo", "abc")
  1768. ->EndObject()
  1769. ->EndObject()
  1770. ->EndObject();
  1771. CheckOutput(out);
  1772. }
  1773. // Test the following case:
  1774. //
  1775. // {
  1776. // "any": {
  1777. // "@type": "type.googleapis.com/google.protobuf.Value",
  1778. // "value": ["hello"],
  1779. // }
  1780. // }
  1781. TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithNestedArrayValue) {
  1782. AnyOut out;
  1783. ::google::protobuf::Any* any = out.mutable_any();
  1784. ::google::protobuf::Value value;
  1785. value.mutable_list_value()->add_values()->set_string_value("hello");
  1786. any->PackFrom(value);
  1787. ow_->StartObject("")
  1788. ->StartObject("any")
  1789. ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
  1790. ->StartList("value")
  1791. ->RenderString("", "hello")
  1792. ->EndList()
  1793. ->EndObject()
  1794. ->EndObject()
  1795. ->EndObject();
  1796. CheckOutput(out);
  1797. }
  1798. // Test the following case:
  1799. //
  1800. // {
  1801. // "any": {
  1802. // "@type": "type.googleapis.com/google.protobuf.Value",
  1803. // "not_value": ""
  1804. // }
  1805. // }
  1806. TEST_P(ProtoStreamObjectWriterAnyTest,
  1807. AnyWellKnownTypesNoValueFieldForPrimitive) {
  1808. EXPECT_CALL(
  1809. listener_,
  1810. InvalidValue(
  1811. _, StringPiece("Any"),
  1812. StringPiece("Expect a \"value\" field for well-known types.")));
  1813. AnyOut any;
  1814. google::protobuf::Any* any_type = any.mutable_any();
  1815. any_type->set_type_url("type.googleapis.com/google.protobuf.Value");
  1816. ow_->StartObject("")
  1817. ->StartObject("any")
  1818. ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
  1819. ->RenderString("not_value", "")
  1820. ->EndObject()
  1821. ->EndObject();
  1822. CheckOutput(any);
  1823. }
  1824. // Test the following case:
  1825. //
  1826. // {
  1827. // "any": {
  1828. // "@type": "type.googleapis.com/google.protobuf.Value",
  1829. // "not_value": {}
  1830. // }
  1831. // }
  1832. TEST_P(ProtoStreamObjectWriterAnyTest, AnyWellKnownTypesNoValueFieldForObject) {
  1833. EXPECT_CALL(
  1834. listener_,
  1835. InvalidValue(
  1836. _, StringPiece("Any"),
  1837. StringPiece("Expect a \"value\" field for well-known types.")));
  1838. AnyOut any;
  1839. google::protobuf::Any* any_type = any.mutable_any();
  1840. any_type->set_type_url("type.googleapis.com/google.protobuf.Value");
  1841. ow_->StartObject("")
  1842. ->StartObject("any")
  1843. ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
  1844. ->StartObject("not_value")
  1845. ->EndObject()
  1846. ->EndObject()
  1847. ->EndObject();
  1848. CheckOutput(any);
  1849. }
  1850. // Test the following case:
  1851. //
  1852. // {
  1853. // "any": {
  1854. // "@type": "type.googleapis.com/google.protobuf.Value",
  1855. // "not_value": [],
  1856. // }
  1857. // }
  1858. TEST_P(ProtoStreamObjectWriterAnyTest, AnyWellKnownTypesNoValueFieldForArray) {
  1859. EXPECT_CALL(
  1860. listener_,
  1861. InvalidValue(
  1862. _, StringPiece("Any"),
  1863. StringPiece("Expect a \"value\" field for well-known types.")));
  1864. AnyOut any;
  1865. google::protobuf::Any* any_type = any.mutable_any();
  1866. any_type->set_type_url("type.googleapis.com/google.protobuf.Value");
  1867. ow_->StartObject("")
  1868. ->StartObject("any")
  1869. ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
  1870. ->StartList("not_value")
  1871. ->EndList()
  1872. ->EndObject()
  1873. ->EndObject()
  1874. ->EndObject();
  1875. CheckOutput(any);
  1876. }
  1877. // Test the following case:
  1878. //
  1879. // {
  1880. // "any": {
  1881. // "@type": "type.googleapis.com/google.protobuf.Struct",
  1882. // "value": "",
  1883. // }
  1884. // }
  1885. TEST_P(ProtoStreamObjectWriterAnyTest, AnyWellKnownTypesExpectObjectForStruct) {
  1886. EXPECT_CALL(listener_, InvalidValue(_, StringPiece("Any"),
  1887. StringPiece("Expect a JSON object.")));
  1888. AnyOut any;
  1889. google::protobuf::Any* any_type = any.mutable_any();
  1890. any_type->set_type_url("type.googleapis.com/google.protobuf.Struct");
  1891. ow_->StartObject("")
  1892. ->StartObject("any")
  1893. ->RenderString("@type", "type.googleapis.com/google.protobuf.Struct")
  1894. ->RenderString("value", "")
  1895. ->EndObject()
  1896. ->EndObject();
  1897. CheckOutput(any);
  1898. }
  1899. // Test the following case:
  1900. //
  1901. // {
  1902. // "any": {
  1903. // "@type": "type.googleapis.com/google.protobuf.Any",
  1904. // "value": "",
  1905. // }
  1906. // }
  1907. TEST_P(ProtoStreamObjectWriterAnyTest, AnyWellKnownTypesExpectObjectForAny) {
  1908. EXPECT_CALL(listener_, InvalidValue(_, StringPiece("Any"),
  1909. StringPiece("Expect a JSON object.")));
  1910. AnyOut any;
  1911. google::protobuf::Any* any_type = any.mutable_any();
  1912. any_type->set_type_url("type.googleapis.com/google.protobuf.Any");
  1913. ow_->StartObject("")
  1914. ->StartObject("any")
  1915. ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
  1916. ->RenderString("value", "")
  1917. ->EndObject()
  1918. ->EndObject();
  1919. CheckOutput(any);
  1920. }
  1921. // {
  1922. // "any": {
  1923. // "@type": "type.googleapis.com/google.protobuf.Any",
  1924. // "value": null
  1925. // }
  1926. // }
  1927. TEST_P(ProtoStreamObjectWriterAnyTest, AnyInAnyAcceptsNull) {
  1928. AnyOut out;
  1929. google::protobuf::Any empty;
  1930. out.mutable_any()->PackFrom(empty);
  1931. EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
  1932. ow_->StartObject("")
  1933. ->StartObject("any")
  1934. ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
  1935. ->RenderNull("value")
  1936. ->EndObject()
  1937. ->EndObject();
  1938. CheckOutput(out);
  1939. }
  1940. // {
  1941. // "any": {
  1942. // "@type": "type.googleapis.com/google.protobuf.Timestamp",
  1943. // "value": null
  1944. // }
  1945. // }
  1946. TEST_P(ProtoStreamObjectWriterAnyTest, TimestampInAnyAcceptsNull) {
  1947. AnyOut out;
  1948. google::protobuf::Timestamp empty;
  1949. out.mutable_any()->PackFrom(empty);
  1950. EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
  1951. ow_->StartObject("")
  1952. ->StartObject("any")
  1953. ->RenderString("@type", "type.googleapis.com/google.protobuf.Timestamp")
  1954. ->RenderNull("value")
  1955. ->EndObject()
  1956. ->EndObject();
  1957. CheckOutput(out);
  1958. }
  1959. // {
  1960. // "any": {
  1961. // "@type": "type.googleapis.com/google.protobuf.Duration",
  1962. // "value": null
  1963. // }
  1964. // }
  1965. TEST_P(ProtoStreamObjectWriterAnyTest, DurationInAnyAcceptsNull) {
  1966. AnyOut out;
  1967. google::protobuf::Duration empty;
  1968. out.mutable_any()->PackFrom(empty);
  1969. EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
  1970. ow_->StartObject("")
  1971. ->StartObject("any")
  1972. ->RenderString("@type", "type.googleapis.com/google.protobuf.Duration")
  1973. ->RenderNull("value")
  1974. ->EndObject()
  1975. ->EndObject();
  1976. CheckOutput(out);
  1977. }
  1978. // {
  1979. // "any": {
  1980. // "@type": "type.googleapis.com/google.protobuf.FieldMask",
  1981. // "value": null
  1982. // }
  1983. // }
  1984. TEST_P(ProtoStreamObjectWriterAnyTest, FieldMaskInAnyAcceptsNull) {
  1985. AnyOut out;
  1986. google::protobuf::FieldMask empty;
  1987. out.mutable_any()->PackFrom(empty);
  1988. EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
  1989. ow_->StartObject("")
  1990. ->StartObject("any")
  1991. ->RenderString("@type", "type.googleapis.com/google.protobuf.FieldMask")
  1992. ->RenderNull("value")
  1993. ->EndObject()
  1994. ->EndObject();
  1995. CheckOutput(out);
  1996. }
  1997. // {
  1998. // "any": {
  1999. // "@type": "type.googleapis.com/google.protobuf.Int32Value",
  2000. // "value": null
  2001. // }
  2002. // }
  2003. TEST_P(ProtoStreamObjectWriterAnyTest, WrapperInAnyAcceptsNull) {
  2004. AnyOut out;
  2005. google::protobuf::Int32Value empty;
  2006. out.mutable_any()->PackFrom(empty);
  2007. EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
  2008. ow_->StartObject("")
  2009. ->StartObject("any")
  2010. ->RenderString("@type", "type.googleapis.com/google.protobuf.Int32Value")
  2011. ->RenderNull("value")
  2012. ->EndObject()
  2013. ->EndObject();
  2014. CheckOutput(out);
  2015. }
  2016. class ProtoStreamObjectWriterFieldMaskTest
  2017. : public BaseProtoStreamObjectWriterTest {
  2018. protected:
  2019. ProtoStreamObjectWriterFieldMaskTest() {
  2020. std::vector<const Descriptor*> descriptors;
  2021. descriptors.push_back(FieldMaskTest::descriptor());
  2022. descriptors.push_back(google::protobuf::FieldMask::descriptor());
  2023. ResetTypeInfo(descriptors);
  2024. }
  2025. };
  2026. INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
  2027. ProtoStreamObjectWriterFieldMaskTest,
  2028. ::testing::Values(
  2029. testing::USE_TYPE_RESOLVER));
  2030. TEST_P(ProtoStreamObjectWriterFieldMaskTest, SimpleFieldMaskTest) {
  2031. FieldMaskTest expected;
  2032. expected.set_id("1");
  2033. expected.mutable_single_mask()->add_paths("path1");
  2034. ow_->StartObject("");
  2035. ow_->RenderString("id", "1");
  2036. ow_->RenderString("single_mask", "path1");
  2037. ow_->EndObject();
  2038. CheckOutput(expected);
  2039. }
  2040. TEST_P(ProtoStreamObjectWriterFieldMaskTest, MutipleMasksInCompactForm) {
  2041. FieldMaskTest expected;
  2042. expected.set_id("1");
  2043. expected.mutable_single_mask()->add_paths("camel_case1");
  2044. expected.mutable_single_mask()->add_paths("camel_case2");
  2045. expected.mutable_single_mask()->add_paths("camel_case3");
  2046. ow_->StartObject("");
  2047. ow_->RenderString("id", "1");
  2048. ow_->RenderString("single_mask", "camelCase1,camelCase2,camelCase3");
  2049. ow_->EndObject();
  2050. CheckOutput(expected);
  2051. }
  2052. TEST_P(ProtoStreamObjectWriterFieldMaskTest, RepeatedFieldMaskTest) {
  2053. FieldMaskTest expected;
  2054. expected.set_id("1");
  2055. google::protobuf::FieldMask* mask = expected.add_repeated_mask();
  2056. mask->add_paths("field1");
  2057. mask->add_paths("field2");
  2058. expected.add_repeated_mask()->add_paths("field3");
  2059. ow_->StartObject("");
  2060. ow_->RenderString("id", "1");
  2061. ow_->StartList("repeated_mask");
  2062. ow_->RenderString("", "field1,field2");
  2063. ow_->RenderString("", "field3");
  2064. ow_->EndList();
  2065. ow_->EndObject();
  2066. CheckOutput(expected);
  2067. }
  2068. TEST_P(ProtoStreamObjectWriterFieldMaskTest, EmptyFieldMaskTest) {
  2069. FieldMaskTest expected;
  2070. expected.set_id("1");
  2071. ow_->StartObject("");
  2072. ow_->RenderString("id", "1");
  2073. ow_->RenderString("single_mask", "");
  2074. ow_->EndObject();
  2075. CheckOutput(expected);
  2076. }
  2077. TEST_P(ProtoStreamObjectWriterFieldMaskTest, MaskUsingApiaryStyleShouldWork) {
  2078. FieldMaskTest expected;
  2079. expected.set_id("1");
  2080. ow_->StartObject("");
  2081. ow_->RenderString("id", "1");
  2082. // Case1
  2083. ow_->RenderString("single_mask",
  2084. "outerField(camelCase1,camelCase2,camelCase3)");
  2085. expected.mutable_single_mask()->add_paths("outer_field.camel_case1");
  2086. expected.mutable_single_mask()->add_paths("outer_field.camel_case2");
  2087. expected.mutable_single_mask()->add_paths("outer_field.camel_case3");
  2088. ow_->StartList("repeated_mask");
  2089. ow_->RenderString("", "a(field1,field2)");
  2090. google::protobuf::FieldMask* mask = expected.add_repeated_mask();
  2091. mask->add_paths("a.field1");
  2092. mask->add_paths("a.field2");
  2093. ow_->RenderString("", "a(field3)");
  2094. mask = expected.add_repeated_mask();
  2095. mask->add_paths("a.field3");
  2096. ow_->RenderString("", "a()");
  2097. expected.add_repeated_mask();
  2098. ow_->RenderString("", "a(,)");
  2099. expected.add_repeated_mask();
  2100. ow_->RenderString("", "a(field1(field2(field3)))");
  2101. mask = expected.add_repeated_mask();
  2102. mask->add_paths("a.field1.field2.field3");
  2103. ow_->RenderString("", "a(field1(field2(field3,field4),field5),field6)");
  2104. mask = expected.add_repeated_mask();
  2105. mask->add_paths("a.field1.field2.field3");
  2106. mask->add_paths("a.field1.field2.field4");
  2107. mask->add_paths("a.field1.field5");
  2108. mask->add_paths("a.field6");
  2109. ow_->RenderString("", "a(id,field1(id,field2(field3,field4),field5),field6)");
  2110. mask = expected.add_repeated_mask();
  2111. mask->add_paths("a.id");
  2112. mask->add_paths("a.field1.id");
  2113. mask->add_paths("a.field1.field2.field3");
  2114. mask->add_paths("a.field1.field2.field4");
  2115. mask->add_paths("a.field1.field5");
  2116. mask->add_paths("a.field6");
  2117. ow_->RenderString("", "a(((field3,field4)))");
  2118. mask = expected.add_repeated_mask();
  2119. mask->add_paths("a.field3");
  2120. mask->add_paths("a.field4");
  2121. ow_->EndList();
  2122. ow_->EndObject();
  2123. CheckOutput(expected);
  2124. }
  2125. TEST_P(ProtoStreamObjectWriterFieldMaskTest, MoreCloseThanOpenParentheses) {
  2126. EXPECT_CALL(
  2127. listener_,
  2128. InvalidValue(
  2129. _, StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
  2130. StringPiece("Field 'single_mask', Invalid FieldMask 'a(b,c))'. "
  2131. "Cannot find matching '(' for all ')'.")));
  2132. ow_->StartObject("");
  2133. ow_->RenderString("id", "1");
  2134. ow_->RenderString("single_mask", "a(b,c))");
  2135. ow_->EndObject();
  2136. }
  2137. TEST_P(ProtoStreamObjectWriterFieldMaskTest, MoreOpenThanCloseParentheses) {
  2138. EXPECT_CALL(
  2139. listener_,
  2140. InvalidValue(
  2141. _, StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
  2142. StringPiece(
  2143. "Field 'single_mask', Invalid FieldMask 'a(((b,c)'. Cannot "
  2144. "find matching ')' for all '('.")));
  2145. ow_->StartObject("");
  2146. ow_->RenderString("id", "1");
  2147. ow_->RenderString("single_mask", "a(((b,c)");
  2148. ow_->EndObject();
  2149. }
  2150. TEST_P(ProtoStreamObjectWriterFieldMaskTest, PathWithMapKeyShouldWork) {
  2151. FieldMaskTest expected;
  2152. expected.mutable_single_mask()->add_paths("path.to.map[\"key1\"]");
  2153. expected.mutable_single_mask()->add_paths(
  2154. "path.to.map[\"e\\\"[]][scape\\\"\"]");
  2155. expected.mutable_single_mask()->add_paths("path.to.map[\"key2\"]");
  2156. ow_->StartObject("");
  2157. ow_->RenderString("single_mask",
  2158. "path.to.map[\"key1\"],path.to.map[\"e\\\"[]][scape\\\"\"],"
  2159. "path.to.map[\"key2\"]");
  2160. ow_->EndObject();
  2161. CheckOutput(expected);
  2162. }
  2163. TEST_P(ProtoStreamObjectWriterFieldMaskTest,
  2164. MapKeyMustBeAtTheEndOfAPathSegment) {
  2165. EXPECT_CALL(
  2166. listener_,
  2167. InvalidValue(
  2168. _, StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
  2169. StringPiece("Field 'single_mask', Invalid FieldMask "
  2170. "'path.to.map[\"key1\"]a,path.to.map[\"key2\"]'. "
  2171. "Map keys should be at the end of a path segment.")));
  2172. ow_->StartObject("");
  2173. ow_->RenderString("single_mask",
  2174. "path.to.map[\"key1\"]a,path.to.map[\"key2\"]");
  2175. ow_->EndObject();
  2176. }
  2177. TEST_P(ProtoStreamObjectWriterFieldMaskTest, MapKeyMustEnd) {
  2178. EXPECT_CALL(
  2179. listener_,
  2180. InvalidValue(_,
  2181. StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
  2182. StringPiece("Field 'single_mask', Invalid FieldMask "
  2183. "'path.to.map[\"key1\"'. Map keys should be "
  2184. "represented as [\"some_key\"].")));
  2185. ow_->StartObject("");
  2186. ow_->RenderString("single_mask", "path.to.map[\"key1\"");
  2187. ow_->EndObject();
  2188. }
  2189. TEST_P(ProtoStreamObjectWriterFieldMaskTest, MapKeyMustBeEscapedCorrectly) {
  2190. EXPECT_CALL(
  2191. listener_,
  2192. InvalidValue(_,
  2193. StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
  2194. StringPiece("Field 'single_mask', Invalid FieldMask "
  2195. "'path.to.map[\"ke\"y1\"]'. Map keys should be "
  2196. "represented as [\"some_key\"].")));
  2197. ow_->StartObject("");
  2198. ow_->RenderString("single_mask", "path.to.map[\"ke\"y1\"]");
  2199. ow_->EndObject();
  2200. }
  2201. TEST_P(ProtoStreamObjectWriterFieldMaskTest, MapKeyCanContainAnyChars) {
  2202. FieldMaskTest expected;
  2203. expected.mutable_single_mask()->add_paths(
  2204. // \xE5\xAD\x99 is the UTF-8 byte sequence for chinese character 孙.
  2205. // We cannot embed non-ASCII characters in the code directly because
  2206. // some windows compilers will try to interpret them using the system's
  2207. // current encoding and end up with invalid UTF-8 byte sequence.
  2208. "path.to.map[\"(),[],\\\"'!@#$%^&*123_|War\xE5\xAD\x99,./?><\\\\\"]");
  2209. expected.mutable_single_mask()->add_paths("path.to.map[\"key2\"]");
  2210. ow_->StartObject("");
  2211. ow_->RenderString(
  2212. "single_mask",
  2213. "path.to.map[\"(),[],\\\"'!@#$%^&*123_|War\xE5\xAD\x99,./?><\\\\\"],"
  2214. "path.to.map[\"key2\"]");
  2215. ow_->EndObject();
  2216. CheckOutput(expected);
  2217. }
  2218. TEST_P(ProtoStreamObjectWriterFieldMaskTest, FieldMaskAcceptsNull) {
  2219. FieldMaskTest expected;
  2220. EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
  2221. ow_->StartObject("")->RenderNull("single_mask")->EndObject();
  2222. CheckOutput(expected);
  2223. }
  2224. class ProtoStreamObjectWriterWrappersTest
  2225. : public BaseProtoStreamObjectWriterTest {
  2226. protected:
  2227. ProtoStreamObjectWriterWrappersTest() {
  2228. std::vector<const Descriptor*> descriptors;
  2229. descriptors.push_back(Int32Wrapper::descriptor());
  2230. descriptors.push_back(google::protobuf::Int32Value::descriptor());
  2231. ResetTypeInfo(descriptors);
  2232. }
  2233. };
  2234. INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
  2235. ProtoStreamObjectWriterWrappersTest,
  2236. ::testing::Values(
  2237. testing::USE_TYPE_RESOLVER));
  2238. TEST_P(ProtoStreamObjectWriterWrappersTest, WrapperAcceptsNull) {
  2239. Int32Wrapper wrapper;
  2240. EXPECT_CALL(listener_, InvalidName(_, _, _)).Times(0);
  2241. ow_->StartObject("")->RenderNull("int32")->EndObject();
  2242. CheckOutput(wrapper);
  2243. }
  2244. class ProtoStreamObjectWriterOneOfsTest
  2245. : public BaseProtoStreamObjectWriterTest {
  2246. protected:
  2247. ProtoStreamObjectWriterOneOfsTest() {
  2248. std::vector<const Descriptor*> descriptors;
  2249. descriptors.push_back(OneOfsRequest::descriptor());
  2250. descriptors.push_back(google::protobuf::Struct::descriptor());
  2251. ResetTypeInfo(descriptors);
  2252. }
  2253. };
  2254. INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
  2255. ProtoStreamObjectWriterOneOfsTest,
  2256. ::testing::Values(
  2257. testing::USE_TYPE_RESOLVER));
  2258. TEST_P(ProtoStreamObjectWriterOneOfsTest,
  2259. MultipleOneofsFailForPrimitiveTypesTest) {
  2260. EXPECT_CALL(
  2261. listener_,
  2262. InvalidValue(
  2263. _, StringPiece("oneof"),
  2264. StringPiece(
  2265. "oneof field 'data' is already set. Cannot set 'intData'")));
  2266. ow_->StartObject("");
  2267. ow_->RenderString("strData", "blah");
  2268. ow_->RenderString("intData", "123");
  2269. ow_->EndObject();
  2270. }
  2271. TEST_P(ProtoStreamObjectWriterOneOfsTest,
  2272. MultipleOneofsFailForMessageTypesPrimitiveFirstTest) {
  2273. // Test for setting primitive oneof field first and then message field.
  2274. EXPECT_CALL(listener_,
  2275. InvalidValue(_, StringPiece("oneof"),
  2276. StringPiece("oneof field 'data' is already set. "
  2277. "Cannot set 'messageData'")));
  2278. // JSON: { "strData": "blah", "messageData": { "dataValue": 123 } }
  2279. ow_->StartObject("");
  2280. ow_->RenderString("strData", "blah");
  2281. ow_->StartObject("messageData");
  2282. ow_->RenderInt32("dataValue", 123);
  2283. ow_->EndObject();
  2284. ow_->EndObject();
  2285. }
  2286. TEST_P(ProtoStreamObjectWriterOneOfsTest,
  2287. MultipleOneofsFailForMessageTypesMessageFirstTest) {
  2288. // Test for setting message oneof field first and then primitive field.
  2289. EXPECT_CALL(listener_,
  2290. InvalidValue(_, StringPiece("oneof"),
  2291. StringPiece("oneof field 'data' is already set. "
  2292. "Cannot set 'strData'")));
  2293. // JSON: { "messageData": { "dataValue": 123 }, "strData": "blah" }
  2294. ow_->StartObject("");
  2295. ow_->StartObject("messageData");
  2296. ow_->RenderInt32("dataValue", 123);
  2297. ow_->EndObject();
  2298. ow_->RenderString("strData", "blah");
  2299. ow_->EndObject();
  2300. }
  2301. TEST_P(ProtoStreamObjectWriterOneOfsTest,
  2302. MultipleOneofsFailForStructTypesPrimitiveFirstTest) {
  2303. EXPECT_CALL(listener_,
  2304. InvalidValue(_, StringPiece("oneof"),
  2305. StringPiece("oneof field 'data' is already set. "
  2306. "Cannot set 'structData'")));
  2307. // JSON: { "strData": "blah", "structData": { "a": "b" } }
  2308. ow_->StartObject("");
  2309. ow_->RenderString("strData", "blah");
  2310. ow_->StartObject("structData");
  2311. ow_->RenderString("a", "b");
  2312. ow_->EndObject();
  2313. ow_->EndObject();
  2314. }
  2315. TEST_P(ProtoStreamObjectWriterOneOfsTest,
  2316. MultipleOneofsFailForStructTypesStructFirstTest) {
  2317. EXPECT_CALL(listener_,
  2318. InvalidValue(_, StringPiece("oneof"),
  2319. StringPiece("oneof field 'data' is already set. "
  2320. "Cannot set 'strData'")));
  2321. // JSON: { "structData": { "a": "b" }, "strData": "blah" }
  2322. ow_->StartObject("");
  2323. ow_->StartObject("structData");
  2324. ow_->RenderString("a", "b");
  2325. ow_->EndObject();
  2326. ow_->RenderString("strData", "blah");
  2327. ow_->EndObject();
  2328. }
  2329. TEST_P(ProtoStreamObjectWriterOneOfsTest,
  2330. MultipleOneofsFailForStructValueTypesTest) {
  2331. EXPECT_CALL(listener_,
  2332. InvalidValue(_, StringPiece("oneof"),
  2333. StringPiece("oneof field 'data' is already set. "
  2334. "Cannot set 'valueData'")));
  2335. // JSON: { "messageData": { "dataValue": 123 }, "valueData": { "a": "b" } }
  2336. ow_->StartObject("");
  2337. ow_->StartObject("messageData");
  2338. ow_->RenderInt32("dataValue", 123);
  2339. ow_->EndObject();
  2340. ow_->StartObject("valueData");
  2341. ow_->RenderString("a", "b");
  2342. ow_->EndObject();
  2343. ow_->EndObject();
  2344. }
  2345. TEST_P(ProtoStreamObjectWriterOneOfsTest,
  2346. MultipleOneofsFailForWellKnownTypesPrimitiveFirstTest) {
  2347. EXPECT_CALL(listener_,
  2348. InvalidValue(_, StringPiece("oneof"),
  2349. StringPiece("oneof field 'data' is already set. "
  2350. "Cannot set 'tsData'")));
  2351. // JSON: { "intData": 123, "tsData": "1970-01-02T01:00:00.000Z" }
  2352. ow_->StartObject("");
  2353. ow_->RenderInt32("intData", 123);
  2354. ow_->RenderString("tsData", "1970-01-02T01:00:00.000Z");
  2355. ow_->EndObject();
  2356. }
  2357. TEST_P(ProtoStreamObjectWriterOneOfsTest,
  2358. MultipleOneofsFailForWellKnownTypesWktFirstTest) {
  2359. EXPECT_CALL(listener_,
  2360. InvalidValue(_, StringPiece("oneof"),
  2361. StringPiece("oneof field 'data' is already set. "
  2362. "Cannot set 'intData'")));
  2363. // JSON: { "tsData": "1970-01-02T01:00:00.000Z", "intData": 123 }
  2364. ow_->StartObject("");
  2365. ow_->RenderString("tsData", "1970-01-02T01:00:00.000Z");
  2366. ow_->RenderInt32("intData", 123);
  2367. ow_->EndObject();
  2368. }
  2369. TEST_P(ProtoStreamObjectWriterOneOfsTest,
  2370. MultipleOneofsFailForWellKnownTypesAndMessageTest) {
  2371. EXPECT_CALL(listener_,
  2372. InvalidValue(_, StringPiece("oneof"),
  2373. StringPiece("oneof field 'data' is already set. "
  2374. "Cannot set 'messageData'")));
  2375. // JSON: { "tsData": "1970-01-02T01:00:00.000Z",
  2376. // "messageData": { "dataValue": 123 } }
  2377. ow_->StartObject("");
  2378. ow_->RenderString("tsData", "1970-01-02T01:00:00.000Z");
  2379. ow_->StartObject("messageData");
  2380. ow_->RenderInt32("dataValue", 123);
  2381. ow_->EndObject();
  2382. ow_->EndObject();
  2383. }
  2384. TEST_P(ProtoStreamObjectWriterOneOfsTest,
  2385. MultipleOneofsFailForOneofWithinAnyTest) {
  2386. EXPECT_CALL(listener_,
  2387. InvalidValue(_, StringPiece("oneof"),
  2388. StringPiece("oneof field 'data' is already set. "
  2389. "Cannot set 'intData'")));
  2390. // JSON:
  2391. // { "anyData":
  2392. // { "@type":
  2393. // "type.googleapis.com/google.protobuf.testing.oneofs.OneOfsRequest",
  2394. // "strData": "blah",
  2395. // "intData": 123
  2396. // }
  2397. // }
  2398. ow_->StartObject("");
  2399. ow_->StartObject("anyData");
  2400. ow_->RenderString(
  2401. "@type",
  2402. "type.googleapis.com/google.protobuf.testing.oneofs.OneOfsRequest");
  2403. ow_->RenderString("strData", "blah");
  2404. ow_->RenderInt32("intData", 123);
  2405. ow_->EndObject();
  2406. ow_->EndObject();
  2407. }
  2408. } // namespace converter
  2409. } // namespace util
  2410. } // namespace protobuf
  2411. } // namespace google