printer_unittest.cc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  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. // Author: kenton@google.com (Kenton Varda)
  31. // Based on original Protocol Buffers design by
  32. // Sanjay Ghemawat, Jeff Dean, and others.
  33. #include <vector>
  34. #include <google/protobuf/io/printer.h>
  35. #include <google/protobuf/io/zero_copy_stream_impl.h>
  36. #include <google/protobuf/descriptor.pb.h>
  37. #include <google/protobuf/stubs/logging.h>
  38. #include <google/protobuf/stubs/common.h>
  39. #include <google/protobuf/testing/googletest.h>
  40. #include <gtest/gtest.h>
  41. namespace google {
  42. namespace protobuf {
  43. namespace io {
  44. namespace {
  45. // Each test repeats over several block sizes in order to test both cases
  46. // where particular writes cross a buffer boundary and cases where they do
  47. // not.
  48. TEST(Printer, EmptyPrinter) {
  49. char buffer[8192];
  50. const int block_size = 100;
  51. ArrayOutputStream output(buffer, GOOGLE_ARRAYSIZE(buffer), block_size);
  52. Printer printer(&output, '\0');
  53. EXPECT_TRUE(!printer.failed());
  54. }
  55. TEST(Printer, BasicPrinting) {
  56. char buffer[8192];
  57. for (int block_size = 1; block_size < 512; block_size *= 2) {
  58. ArrayOutputStream output(buffer, sizeof(buffer), block_size);
  59. {
  60. Printer printer(&output, '\0');
  61. printer.Print("Hello World!");
  62. printer.Print(" This is the same line.\n");
  63. printer.Print("But this is a new one.\nAnd this is another one.");
  64. EXPECT_FALSE(printer.failed());
  65. }
  66. buffer[output.ByteCount()] = '\0';
  67. EXPECT_STREQ("Hello World! This is the same line.\n"
  68. "But this is a new one.\n"
  69. "And this is another one.",
  70. buffer);
  71. }
  72. }
  73. TEST(Printer, WriteRaw) {
  74. char buffer[8192];
  75. for (int block_size = 1; block_size < 512; block_size *= 2) {
  76. ArrayOutputStream output(buffer, sizeof(buffer), block_size);
  77. {
  78. string string_obj = "From an object\n";
  79. Printer printer(&output, '$');
  80. printer.WriteRaw("Hello World!", 12);
  81. printer.PrintRaw(" This is the same line.\n");
  82. printer.PrintRaw("But this is a new one.\nAnd this is another one.");
  83. printer.WriteRaw("\n", 1);
  84. printer.PrintRaw(string_obj);
  85. EXPECT_FALSE(printer.failed());
  86. }
  87. buffer[output.ByteCount()] = '\0';
  88. EXPECT_STREQ("Hello World! This is the same line.\n"
  89. "But this is a new one.\n"
  90. "And this is another one."
  91. "\n"
  92. "From an object\n",
  93. buffer);
  94. }
  95. }
  96. TEST(Printer, VariableSubstitution) {
  97. char buffer[8192];
  98. for (int block_size = 1; block_size < 512; block_size *= 2) {
  99. ArrayOutputStream output(buffer, sizeof(buffer), block_size);
  100. {
  101. Printer printer(&output, '$');
  102. std::map<string, string> vars;
  103. vars["foo"] = "World";
  104. vars["bar"] = "$foo$";
  105. vars["abcdefg"] = "1234";
  106. printer.Print(vars, "Hello $foo$!\nbar = $bar$\n");
  107. printer.PrintRaw("RawBit\n");
  108. printer.Print(vars, "$abcdefg$\nA literal dollar sign: $$");
  109. vars["foo"] = "blah";
  110. printer.Print(vars, "\nNow foo = $foo$.");
  111. EXPECT_FALSE(printer.failed());
  112. }
  113. buffer[output.ByteCount()] = '\0';
  114. EXPECT_STREQ("Hello World!\n"
  115. "bar = $foo$\n"
  116. "RawBit\n"
  117. "1234\n"
  118. "A literal dollar sign: $\n"
  119. "Now foo = blah.",
  120. buffer);
  121. }
  122. }
  123. TEST(Printer, InlineVariableSubstitution) {
  124. char buffer[8192];
  125. ArrayOutputStream output(buffer, sizeof(buffer));
  126. {
  127. Printer printer(&output, '$');
  128. printer.Print("Hello $foo$!\n", "foo", "World");
  129. printer.PrintRaw("RawBit\n");
  130. printer.Print("$foo$ $bar$\n", "foo", "one", "bar", "two");
  131. EXPECT_FALSE(printer.failed());
  132. }
  133. buffer[output.ByteCount()] = '\0';
  134. EXPECT_STREQ("Hello World!\n"
  135. "RawBit\n"
  136. "one two\n",
  137. buffer);
  138. }
  139. // MockDescriptorFile defines only those members that Printer uses to write out
  140. // annotations.
  141. class MockDescriptorFile {
  142. public:
  143. explicit MockDescriptorFile(const string& file) : file_(file) {}
  144. // The mock filename for this file.
  145. const string& name() const { return file_; }
  146. private:
  147. string file_;
  148. };
  149. // MockDescriptor defines only those members that Printer uses to write out
  150. // annotations.
  151. class MockDescriptor {
  152. public:
  153. MockDescriptor(const string& file, const std::vector<int>& path)
  154. : file_(file), path_(path) {}
  155. // The mock file in which this descriptor was defined.
  156. const MockDescriptorFile* file() const { return &file_; }
  157. private:
  158. // Allows access to GetLocationPath.
  159. friend class ::google::protobuf::io::Printer;
  160. // Copies the pre-stored path to output.
  161. void GetLocationPath(std::vector<int>* output) const { *output = path_; }
  162. MockDescriptorFile file_;
  163. std::vector<int> path_;
  164. };
  165. TEST(Printer, AnnotateMap) {
  166. char buffer[8192];
  167. ArrayOutputStream output(buffer, sizeof(buffer));
  168. GeneratedCodeInfo info;
  169. AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
  170. {
  171. Printer printer(&output, '$', &info_collector);
  172. std::map<string, string> vars;
  173. vars["foo"] = "3";
  174. vars["bar"] = "5";
  175. printer.Print(vars, "012$foo$4$bar$\n");
  176. std::vector<int> path_1;
  177. path_1.push_back(33);
  178. std::vector<int> path_2;
  179. path_2.push_back(11);
  180. path_2.push_back(22);
  181. MockDescriptor descriptor_1("path_1", path_1);
  182. MockDescriptor descriptor_2("path_2", path_2);
  183. printer.Annotate("foo", "foo", &descriptor_1);
  184. printer.Annotate("bar", "bar", &descriptor_2);
  185. }
  186. buffer[output.ByteCount()] = '\0';
  187. EXPECT_STREQ("012345\n", buffer);
  188. ASSERT_EQ(2, info.annotation_size());
  189. const GeneratedCodeInfo::Annotation* foo = info.annotation(0).path_size() == 1
  190. ? &info.annotation(0)
  191. : &info.annotation(1);
  192. const GeneratedCodeInfo::Annotation* bar = info.annotation(0).path_size() == 1
  193. ? &info.annotation(1)
  194. : &info.annotation(0);
  195. ASSERT_EQ(1, foo->path_size());
  196. ASSERT_EQ(2, bar->path_size());
  197. EXPECT_EQ(33, foo->path(0));
  198. EXPECT_EQ(11, bar->path(0));
  199. EXPECT_EQ(22, bar->path(1));
  200. EXPECT_EQ("path_1", foo->source_file());
  201. EXPECT_EQ("path_2", bar->source_file());
  202. EXPECT_EQ(3, foo->begin());
  203. EXPECT_EQ(4, foo->end());
  204. EXPECT_EQ(5, bar->begin());
  205. EXPECT_EQ(6, bar->end());
  206. }
  207. TEST(Printer, AnnotateInline) {
  208. char buffer[8192];
  209. ArrayOutputStream output(buffer, sizeof(buffer));
  210. GeneratedCodeInfo info;
  211. AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
  212. {
  213. Printer printer(&output, '$', &info_collector);
  214. printer.Print("012$foo$4$bar$\n", "foo", "3", "bar", "5");
  215. std::vector<int> path_1;
  216. path_1.push_back(33);
  217. std::vector<int> path_2;
  218. path_2.push_back(11);
  219. path_2.push_back(22);
  220. MockDescriptor descriptor_1("path_1", path_1);
  221. MockDescriptor descriptor_2("path_2", path_2);
  222. printer.Annotate("foo", "foo", &descriptor_1);
  223. printer.Annotate("bar", "bar", &descriptor_2);
  224. }
  225. buffer[output.ByteCount()] = '\0';
  226. EXPECT_STREQ("012345\n", buffer);
  227. ASSERT_EQ(2, info.annotation_size());
  228. const GeneratedCodeInfo::Annotation* foo = info.annotation(0).path_size() == 1
  229. ? &info.annotation(0)
  230. : &info.annotation(1);
  231. const GeneratedCodeInfo::Annotation* bar = info.annotation(0).path_size() == 1
  232. ? &info.annotation(1)
  233. : &info.annotation(0);
  234. ASSERT_EQ(1, foo->path_size());
  235. ASSERT_EQ(2, bar->path_size());
  236. EXPECT_EQ(33, foo->path(0));
  237. EXPECT_EQ(11, bar->path(0));
  238. EXPECT_EQ(22, bar->path(1));
  239. EXPECT_EQ("path_1", foo->source_file());
  240. EXPECT_EQ("path_2", bar->source_file());
  241. EXPECT_EQ(3, foo->begin());
  242. EXPECT_EQ(4, foo->end());
  243. EXPECT_EQ(5, bar->begin());
  244. EXPECT_EQ(6, bar->end());
  245. }
  246. TEST(Printer, AnnotateRange) {
  247. char buffer[8192];
  248. ArrayOutputStream output(buffer, sizeof(buffer));
  249. GeneratedCodeInfo info;
  250. AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
  251. {
  252. Printer printer(&output, '$', &info_collector);
  253. printer.Print("012$foo$4$bar$\n", "foo", "3", "bar", "5");
  254. std::vector<int> path;
  255. path.push_back(33);
  256. MockDescriptor descriptor("path", path);
  257. printer.Annotate("foo", "bar", &descriptor);
  258. }
  259. buffer[output.ByteCount()] = '\0';
  260. EXPECT_STREQ("012345\n", buffer);
  261. ASSERT_EQ(1, info.annotation_size());
  262. const GeneratedCodeInfo::Annotation* foobar = &info.annotation(0);
  263. ASSERT_EQ(1, foobar->path_size());
  264. EXPECT_EQ(33, foobar->path(0));
  265. EXPECT_EQ("path", foobar->source_file());
  266. EXPECT_EQ(3, foobar->begin());
  267. EXPECT_EQ(6, foobar->end());
  268. }
  269. TEST(Printer, AnnotateEmptyRange) {
  270. char buffer[8192];
  271. ArrayOutputStream output(buffer, sizeof(buffer));
  272. GeneratedCodeInfo info;
  273. AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
  274. {
  275. Printer printer(&output, '$', &info_collector);
  276. printer.Print("012$foo$4$baz$$bam$$bar$\n", "foo", "3", "bar", "5", "baz",
  277. "", "bam", "");
  278. std::vector<int> path;
  279. path.push_back(33);
  280. MockDescriptor descriptor("path", path);
  281. printer.Annotate("baz", "bam", &descriptor);
  282. }
  283. buffer[output.ByteCount()] = '\0';
  284. EXPECT_STREQ("012345\n", buffer);
  285. ASSERT_EQ(1, info.annotation_size());
  286. const GeneratedCodeInfo::Annotation* bazbam = &info.annotation(0);
  287. ASSERT_EQ(1, bazbam->path_size());
  288. EXPECT_EQ(33, bazbam->path(0));
  289. EXPECT_EQ("path", bazbam->source_file());
  290. EXPECT_EQ(5, bazbam->begin());
  291. EXPECT_EQ(5, bazbam->end());
  292. }
  293. TEST(Printer, AnnotateDespiteUnrelatedMultipleUses) {
  294. char buffer[8192];
  295. ArrayOutputStream output(buffer, sizeof(buffer));
  296. GeneratedCodeInfo info;
  297. AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
  298. {
  299. Printer printer(&output, '$', &info_collector);
  300. printer.Print("012$foo$4$foo$$bar$\n", "foo", "3", "bar", "5");
  301. std::vector<int> path;
  302. path.push_back(33);
  303. MockDescriptor descriptor("path", path);
  304. printer.Annotate("bar", "bar", &descriptor);
  305. }
  306. buffer[output.ByteCount()] = '\0';
  307. EXPECT_STREQ("0123435\n", buffer);
  308. ASSERT_EQ(1, info.annotation_size());
  309. const GeneratedCodeInfo::Annotation* bar = &info.annotation(0);
  310. ASSERT_EQ(1, bar->path_size());
  311. EXPECT_EQ(33, bar->path(0));
  312. EXPECT_EQ("path", bar->source_file());
  313. EXPECT_EQ(6, bar->begin());
  314. EXPECT_EQ(7, bar->end());
  315. }
  316. TEST(Printer, AnnotateIndent) {
  317. char buffer[8192];
  318. ArrayOutputStream output(buffer, sizeof(buffer));
  319. GeneratedCodeInfo info;
  320. AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
  321. {
  322. Printer printer(&output, '$', &info_collector);
  323. printer.Print("0\n");
  324. printer.Indent();
  325. printer.Print("$foo$", "foo", "4");
  326. std::vector<int> path;
  327. path.push_back(44);
  328. MockDescriptor descriptor("path", path);
  329. printer.Annotate("foo", &descriptor);
  330. printer.Print(",\n");
  331. printer.Print("$bar$", "bar", "9");
  332. path[0] = 99;
  333. MockDescriptor descriptor_two("path", path);
  334. printer.Annotate("bar", &descriptor_two);
  335. printer.Print("\n${$$D$$}$\n", "{", "", "}", "", "D", "d");
  336. path[0] = 1313;
  337. MockDescriptor descriptor_three("path", path);
  338. printer.Annotate("{", "}", &descriptor_three);
  339. printer.Outdent();
  340. printer.Print("\n");
  341. }
  342. buffer[output.ByteCount()] = '\0';
  343. EXPECT_STREQ("0\n 4,\n 9\n d\n\n", buffer);
  344. ASSERT_EQ(3, info.annotation_size());
  345. const GeneratedCodeInfo::Annotation* foo = &info.annotation(0);
  346. ASSERT_EQ(1, foo->path_size());
  347. EXPECT_EQ(44, foo->path(0));
  348. EXPECT_EQ("path", foo->source_file());
  349. EXPECT_EQ(4, foo->begin());
  350. EXPECT_EQ(5, foo->end());
  351. const GeneratedCodeInfo::Annotation* bar = &info.annotation(1);
  352. ASSERT_EQ(1, bar->path_size());
  353. EXPECT_EQ(99, bar->path(0));
  354. EXPECT_EQ("path", bar->source_file());
  355. EXPECT_EQ(9, bar->begin());
  356. EXPECT_EQ(10, bar->end());
  357. const GeneratedCodeInfo::Annotation* braces = &info.annotation(2);
  358. ASSERT_EQ(1, braces->path_size());
  359. EXPECT_EQ(1313, braces->path(0));
  360. EXPECT_EQ("path", braces->source_file());
  361. EXPECT_EQ(13, braces->begin());
  362. EXPECT_EQ(14, braces->end());
  363. }
  364. TEST(Printer, AnnotateIndentNewline) {
  365. char buffer[8192];
  366. ArrayOutputStream output(buffer, sizeof(buffer));
  367. GeneratedCodeInfo info;
  368. AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
  369. {
  370. Printer printer(&output, '$', &info_collector);
  371. printer.Indent();
  372. printer.Print("$A$$N$$B$C\n", "A", "", "N", "\nz", "B", "");
  373. std::vector<int> path;
  374. path.push_back(0);
  375. MockDescriptor descriptor("path", path);
  376. printer.Annotate("A", "B", &descriptor);
  377. printer.Outdent();
  378. printer.Print("\n");
  379. }
  380. buffer[output.ByteCount()] = '\0';
  381. EXPECT_STREQ("\nz C\n\n", buffer);
  382. ASSERT_EQ(1, info.annotation_size());
  383. const GeneratedCodeInfo::Annotation* ab = &info.annotation(0);
  384. ASSERT_EQ(1, ab->path_size());
  385. EXPECT_EQ(0, ab->path(0));
  386. EXPECT_EQ("path", ab->source_file());
  387. EXPECT_EQ(0, ab->begin());
  388. EXPECT_EQ(4, ab->end());
  389. }
  390. TEST(Printer, Indenting) {
  391. char buffer[8192];
  392. for (int block_size = 1; block_size < 512; block_size *= 2) {
  393. ArrayOutputStream output(buffer, sizeof(buffer), block_size);
  394. {
  395. Printer printer(&output, '$');
  396. std::map<string, string> vars;
  397. vars["newline"] = "\n";
  398. printer.Print("This is not indented.\n");
  399. printer.Indent();
  400. printer.Print("This is indented\nAnd so is this\n");
  401. printer.Outdent();
  402. printer.Print("But this is not.");
  403. printer.Indent();
  404. printer.Print(" And this is still the same line.\n"
  405. "But this is indented.\n");
  406. printer.PrintRaw("RawBit has indent at start\n");
  407. printer.PrintRaw("but not after a raw newline\n");
  408. printer.Print(vars, "Note that a newline in a variable will break "
  409. "indenting, as we see$newline$here.\n");
  410. printer.Indent();
  411. printer.Print("And this");
  412. printer.Outdent();
  413. printer.Outdent();
  414. printer.Print(" is double-indented\nBack to normal.");
  415. EXPECT_FALSE(printer.failed());
  416. }
  417. buffer[output.ByteCount()] = '\0';
  418. EXPECT_STREQ(
  419. "This is not indented.\n"
  420. " This is indented\n"
  421. " And so is this\n"
  422. "But this is not. And this is still the same line.\n"
  423. " But this is indented.\n"
  424. " RawBit has indent at start\n"
  425. "but not after a raw newline\n"
  426. "Note that a newline in a variable will break indenting, as we see\n"
  427. "here.\n"
  428. " And this is double-indented\n"
  429. "Back to normal.",
  430. buffer);
  431. }
  432. }
  433. // Death tests do not work on Windows as of yet.
  434. #ifdef PROTOBUF_HAS_DEATH_TEST
  435. TEST(Printer, Death) {
  436. char buffer[8192];
  437. ArrayOutputStream output(buffer, sizeof(buffer));
  438. Printer printer(&output, '$');
  439. EXPECT_DEBUG_DEATH(printer.Print("$nosuchvar$"), "Undefined variable");
  440. EXPECT_DEBUG_DEATH(printer.Print("$unclosed"), "Unclosed variable name");
  441. EXPECT_DEBUG_DEATH(printer.Outdent(), "without matching Indent");
  442. }
  443. TEST(Printer, AnnotateMultipleUsesDeath) {
  444. char buffer[8192];
  445. ArrayOutputStream output(buffer, sizeof(buffer));
  446. GeneratedCodeInfo info;
  447. AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
  448. {
  449. Printer printer(&output, '$', &info_collector);
  450. printer.Print("012$foo$4$foo$\n", "foo", "3");
  451. std::vector<int> path;
  452. path.push_back(33);
  453. MockDescriptor descriptor("path", path);
  454. EXPECT_DEBUG_DEATH(printer.Annotate("foo", "foo", &descriptor), "multiple");
  455. }
  456. }
  457. TEST(Printer, AnnotateNegativeLengthDeath) {
  458. char buffer[8192];
  459. ArrayOutputStream output(buffer, sizeof(buffer));
  460. GeneratedCodeInfo info;
  461. AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
  462. {
  463. Printer printer(&output, '$', &info_collector);
  464. printer.Print("012$foo$4$bar$\n", "foo", "3", "bar", "5");
  465. std::vector<int> path;
  466. path.push_back(33);
  467. MockDescriptor descriptor("path", path);
  468. EXPECT_DEBUG_DEATH(printer.Annotate("bar", "foo", &descriptor), "negative");
  469. }
  470. }
  471. TEST(Printer, AnnotateUndefinedDeath) {
  472. char buffer[8192];
  473. ArrayOutputStream output(buffer, sizeof(buffer));
  474. GeneratedCodeInfo info;
  475. AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
  476. {
  477. Printer printer(&output, '$', &info_collector);
  478. printer.Print("012$foo$4$foo$\n", "foo", "3");
  479. std::vector<int> path;
  480. path.push_back(33);
  481. MockDescriptor descriptor("path", path);
  482. EXPECT_DEBUG_DEATH(printer.Annotate("bar", "bar", &descriptor),
  483. "Undefined");
  484. }
  485. }
  486. #endif // PROTOBUF_HAS_DEATH_TEST
  487. TEST(Printer, WriteFailurePartial) {
  488. char buffer[17];
  489. ArrayOutputStream output(buffer, sizeof(buffer));
  490. Printer printer(&output, '$');
  491. // Print 16 bytes to almost fill the buffer (should not fail).
  492. printer.Print("0123456789abcdef");
  493. EXPECT_FALSE(printer.failed());
  494. // Try to print 2 chars. Only one fits.
  495. printer.Print("<>");
  496. EXPECT_TRUE(printer.failed());
  497. // Anything else should fail too.
  498. printer.Print(" ");
  499. EXPECT_TRUE(printer.failed());
  500. printer.Print("blah");
  501. EXPECT_TRUE(printer.failed());
  502. // Buffer should contain the first 17 bytes written.
  503. EXPECT_EQ("0123456789abcdef<", string(buffer, sizeof(buffer)));
  504. }
  505. TEST(Printer, WriteFailureExact) {
  506. char buffer[16];
  507. ArrayOutputStream output(buffer, sizeof(buffer));
  508. Printer printer(&output, '$');
  509. // Print 16 bytes to fill the buffer exactly (should not fail).
  510. printer.Print("0123456789abcdef");
  511. EXPECT_FALSE(printer.failed());
  512. // Try to print one more byte (should fail).
  513. printer.Print(" ");
  514. EXPECT_TRUE(printer.failed());
  515. // Should not crash
  516. printer.Print("blah");
  517. EXPECT_TRUE(printer.failed());
  518. // Buffer should contain the first 16 bytes written.
  519. EXPECT_EQ("0123456789abcdef", string(buffer, sizeof(buffer)));
  520. }
  521. } // namespace
  522. } // namespace io
  523. } // namespace protobuf
  524. } // namespace google