15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Protocol Buffers - Google's data interchange format
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2008 Google Inc.  All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/protobuf/
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met:
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions of source code must retain the above copyright
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions in binary form must reproduce the above
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// in the documentation and/or other materials provided with the
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// distribution.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Neither the name of Google Inc. nor the names of its
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: kenton@google.com (Kenton Varda)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  Based on original Protocol Buffers design by
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  Sanjay Ghemawat, Jeff Dean, and others.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/printer.h>
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/zero_copy_stream_impl.h>
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/common.h>
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/testing/googletest.h>
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gtest/gtest.h>
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace io {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Each test repeats over several block sizes in order to test both cases
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// where particular writes cross a buffer boundary and cases where they do
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Printer, EmptyPrinter) {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char buffer[8192];
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int block_size = 100;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayOutputStream output(buffer, GOOGLE_ARRAYSIZE(buffer), block_size);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Printer printer(&output, '\0');
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(!printer.failed());
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Printer, BasicPrinting) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char buffer[8192];
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int block_size = 1; block_size < 512; block_size *= 2) {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ArrayOutputStream output(buffer, sizeof(buffer), block_size);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Printer printer(&output, '\0');
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.Print("Hello World!");
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.Print("  This is the same line.\n");
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.Print("But this is a new one.\nAnd this is another one.");
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_FALSE(printer.failed());
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buffer[output.ByteCount()] = '\0';
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_STREQ("Hello World!  This is the same line.\n"
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 "But this is a new one.\n"
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 "And this is another one.",
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 buffer);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Printer, WriteRaw) {
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  char buffer[8192];
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int block_size = 1; block_size < 512; block_size *= 2) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ArrayOutputStream output(buffer, sizeof(buffer), block_size);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      string string_obj = "From an object\n";
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Printer printer(&output, '$');
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.WriteRaw("Hello World!", 12);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.PrintRaw("  This is the same line.\n");
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.PrintRaw("But this is a new one.\nAnd this is another one.");
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.WriteRaw("\n", 1);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.PrintRaw(string_obj);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_FALSE(printer.failed());
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buffer[output.ByteCount()] = '\0';
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_STREQ("Hello World!  This is the same line.\n"
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 "But this is a new one.\n"
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 "And this is another one."
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 "\n"
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 "From an object\n",
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 buffer);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(Printer, VariableSubstitution) {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char buffer[8192];
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int block_size = 1; block_size < 512; block_size *= 2) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ArrayOutputStream output(buffer, sizeof(buffer), block_size);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Printer printer(&output, '$');
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      map<string, string> vars;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      vars["foo"] = "World";
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      vars["bar"] = "$foo$";
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      vars["abcdefg"] = "1234";
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      printer.Print(vars, "Hello $foo$!\nbar = $bar$\n");
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.PrintRaw("RawBit\n");
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.Print(vars, "$abcdefg$\nA literal dollar sign:  $$");
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      vars["foo"] = "blah";
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.Print(vars, "\nNow foo = $foo$.");
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_FALSE(printer.failed());
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buffer[output.ByteCount()] = '\0';
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_STREQ("Hello World!\n"
1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 "bar = $foo$\n"
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 "RawBit\n"
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 "1234\n"
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 "A literal dollar sign:  $\n"
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 "Now foo = blah.",
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 buffer);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Printer, InlineVariableSubstitution) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char buffer[8192];
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayOutputStream output(buffer, sizeof(buffer));
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Printer printer(&output, '$');
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer.Print("Hello $foo$!\n", "foo", "World");
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer.PrintRaw("RawBit\n");
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer.Print("$foo$ $bar$\n", "foo", "one", "bar", "two");
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(printer.failed());
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buffer[output.ByteCount()] = '\0';
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("Hello World!\n"
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "RawBit\n"
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "one two\n",
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               buffer);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Printer, Indenting) {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char buffer[8192];
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int block_size = 1; block_size < 512; block_size *= 2) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ArrayOutputStream output(buffer, sizeof(buffer), block_size);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Printer printer(&output, '$');
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      map<string, string> vars;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      vars["newline"] = "\n";
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.Print("This is not indented.\n");
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.Indent();
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.Print("This is indented\nAnd so is this\n");
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.Outdent();
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.Print("But this is not.");
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.Indent();
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.Print("  And this is still the same line.\n"
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    "But this is indented.\n");
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.PrintRaw("RawBit has indent at start\n");
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.PrintRaw("but not after a raw newline\n");
1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      printer.Print(vars, "Note that a newline in a variable will break "
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    "indenting, as we see$newline$here.\n");
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.Indent();
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.Print("And this");
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.Outdent();
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.Outdent();
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer.Print(" is double-indented\nBack to normal.");
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_FALSE(printer.failed());
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buffer[output.ByteCount()] = '\0';
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_STREQ(
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "This is not indented.\n"
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "  This is indented\n"
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "  And so is this\n"
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "But this is not.  And this is still the same line.\n"
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "  But this is indented.\n"
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "  RawBit has indent at start\n"
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "but not after a raw newline\n"
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Note that a newline in a variable will break indenting, as we see\n"
2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      "here.\n"
2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      "    And this is double-indented\n"
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Back to normal.",
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      buffer);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Death tests do not work on Windows as of yet.
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef GTEST_HAS_DEATH_TEST
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Printer, Death) {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char buffer[8192];
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayOutputStream output(buffer, sizeof(buffer));
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Printer printer(&output, '$');
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_DEBUG_DEATH(printer.Print("$nosuchvar$"), "Undefined variable");
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_DEBUG_DEATH(printer.Print("$unclosed"), "Unclosed variable name");
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_DEBUG_DEATH(printer.Outdent(), "without matching Indent");
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // GTEST_HAS_DEATH_TEST
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Printer, WriteFailure) {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char buffer[16];
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayOutputStream output(buffer, sizeof(buffer));
2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Printer printer(&output, '$');
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Print 16 bytes to fill the buffer exactly (should not fail).
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  printer.Print("0123456789abcdef");
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(printer.failed());
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Try to print one more byte (should fail).
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  printer.Print(" ");
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(printer.failed());
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Should not crash
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer.Print("blah");
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(printer.failed());
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Buffer should contain the first 16 bytes written.
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0123456789abcdef", string(buffer, sizeof(buffer)));
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace io
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace protobuf
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace google
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)