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
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the
145821806d5e7f356e8fa4b058a389a808ea183019Torne (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
285821806d5e7f356e8fa4b058a389a808ea183019Torne (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: jschorr@google.com (Joseph Schorr)
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 <math.h>
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits>
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/text_format.h>
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/zero_copy_stream_impl.h>
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/tokenizer.h>
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/unittest.pb.h>
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/unittest_mset.pb.h>
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/test_util.h>
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/common.h>
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/testing/file.h>
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/testing/googletest.h>
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gtest/gtest.h>
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/strutil.h>
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/substitute.h>
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace text_format_unittest {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline bool IsNaN(double value) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NaN is never equal to anything, even itself.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return value != value;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A basic string with different escapable characters for testing.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const string kEscapeTestString =
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "\"A string with ' characters \n and \r newlines and \t tabs and \001 "
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "slashes \\ and  multiple   spaces";
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A representation of the above string with all the characters escaped.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const string kEscapeTestStringEscaped =
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "\"\\\"A string with \\' characters \\n and \\r newlines "
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "and \\t tabs and \\001 slashes \\\\ and  multiple   spaces\"";
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TextFormatTest : public testing::Test {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void SetUpTestCase() {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    File::ReadFileToStringOrDie(
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestSourceDir()
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        + "/google/protobuf/testdata/text_format_unittest_data.txt",
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &static_proto_debug_string_);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TextFormatTest() : proto_debug_string_(static_proto_debug_string_) {}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Debug string read from text_format_unittest_data.txt.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const string proto_debug_string_;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestAllTypes proto_;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static string static_proto_debug_string_;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string TextFormatTest::static_proto_debug_string_;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TextFormatExtensionsTest : public testing::Test {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void SetUpTestCase() {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    File::ReadFileToStringOrDie(
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestSourceDir()
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        + "/google/protobuf/testdata/"
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "text_format_unittest_extensions_data.txt",
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &static_proto_debug_string_);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TextFormatExtensionsTest()
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : proto_debug_string_(static_proto_debug_string_) {}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Debug string read from text_format_unittest_data.txt.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const string proto_debug_string_;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestAllExtensions proto_;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static string static_proto_debug_string_;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string TextFormatExtensionsTest::static_proto_debug_string_;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatTest, Basic) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::SetAllFields(&proto_);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(proto_debug_string_, proto_.DebugString());
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatExtensionsTest, Extensions) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::SetAllExtensions(&proto_);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(proto_debug_string_, proto_.DebugString());
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatTest, ShortDebugString) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proto_.set_optional_int32(1);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proto_.set_optional_string("hello");
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proto_.mutable_optional_nested_message()->set_bb(2);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proto_.mutable_optional_foreign_message();
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("optional_int32: 1 optional_string: \"hello\" "
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "optional_nested_message { bb: 2 } "
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "optional_foreign_message { }",
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            proto_.ShortDebugString());
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatTest, ShortPrimitiveRepeateds) {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proto_.set_optional_int32(123);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proto_.add_repeated_int32(456);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proto_.add_repeated_int32(789);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proto_.add_repeated_string("foo");
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proto_.add_repeated_string("bar");
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proto_.add_repeated_nested_message()->set_bb(2);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proto_.add_repeated_nested_message()->set_bb(3);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proto_.add_repeated_nested_enum(unittest::TestAllTypes::FOO);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proto_.add_repeated_nested_enum(unittest::TestAllTypes::BAR);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TextFormat::Printer printer;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer.SetUseShortRepeatedPrimitives(true);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string text;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer.PrintToString(proto_, &text);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("optional_int32: 123\n"
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "repeated_int32: [456, 789]\n"
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "repeated_string: \"foo\"\n"
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "repeated_string: \"bar\"\n"
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "repeated_nested_message {\n  bb: 2\n}\n"
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "repeated_nested_message {\n  bb: 3\n}\n"
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "repeated_nested_enum: [FOO, BAR]\n",
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            text);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try in single-line mode.
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer.SetSingleLineMode(true);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer.PrintToString(proto_, &text);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("optional_int32: 123 "
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "repeated_int32: [456, 789] "
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "repeated_string: \"foo\" "
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "repeated_string: \"bar\" "
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "repeated_nested_message { bb: 2 } "
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "repeated_nested_message { bb: 3 } "
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "repeated_nested_enum: [FOO, BAR] ",
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            text);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatTest, StringEscape) {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the string value to test.
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proto_.set_optional_string(kEscapeTestString);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the DebugString from the proto.
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string debug_string = proto_.DebugString();
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string utf8_debug_string = proto_.Utf8DebugString();
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Hardcode a correct value to test against.
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string correct_string = "optional_string: "
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      + kEscapeTestStringEscaped
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       + "\n";
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Compare.
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(correct_string, debug_string);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // UTF-8 string is the same as non-UTF-8 because
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the protocol buffer contains no UTF-8 text.
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(correct_string, utf8_debug_string);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string expected_short_debug_string = "optional_string: "
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      + kEscapeTestStringEscaped;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_short_debug_string, proto_.ShortDebugString());
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatTest, Utf8DebugString) {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the string value to test.
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proto_.set_optional_string("\350\260\267\346\255\214");
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the DebugString from the proto.
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string debug_string = proto_.DebugString();
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string utf8_debug_string = proto_.Utf8DebugString();
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Hardcode a correct value to test against.
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string correct_utf8_string = "optional_string: "
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\"\350\260\267\346\255\214\""
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n";
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string correct_string = "optional_string: "
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\"\\350\\260\\267\\346\\255\\214\""
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n";
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Compare.
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(correct_utf8_string, utf8_debug_string);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(correct_string, debug_string);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatTest, PrintUnknownFields) {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test printing of unknown fields in a message.
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestEmptyMessage message;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UnknownFieldSet* unknown_fields = message.mutable_unknown_fields();
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unknown_fields->AddVarint(5, 1);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unknown_fields->AddFixed32(5, 2);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unknown_fields->AddFixed64(5, 3);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unknown_fields->AddLengthDelimited(5, "4");
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unknown_fields->AddGroup(5)->AddVarint(10, 5);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unknown_fields->AddVarint(8, 1);
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unknown_fields->AddVarint(8, 2);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unknown_fields->AddVarint(8, 3);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "5: 1\n"
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "5: 0x00000002\n"
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "5: 0x0000000000000003\n"
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "5: \"4\"\n"
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "5 {\n"
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  10: 5\n"
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}\n"
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "8: 1\n"
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "8: 2\n"
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "8: 3\n",
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message.DebugString());
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatTest, PrintUnknownMessage) {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test heuristic printing of messages in an UnknownFieldSet.
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protobuf_unittest::TestAllTypes message;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cases which should not be interpreted as sub-messages.
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 'a' is a valid FIXED64 tag, so for the string to be parseable as a message
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it should be followed by 8 bytes.  Since this string only has two
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // subsequent bytes, it should be treated as a string.
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_string("abc");
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 'd' happens to be a valid ENDGROUP tag.  So,
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // UnknownFieldSet::MergeFromCodedStream() will successfully parse "def", but
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the ConsumedEntireMessage() check should fail.
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_string("def");
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A zero-length string should never be interpreted as a message even though
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it is technically valid as one.
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_string("");
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Case which should be interpreted as a sub-message.
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An actual nested message with content should always be interpreted as a
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // nested message.
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_nested_message()->set_bb(123);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string data;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.SerializeToString(&data);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string text;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UnknownFieldSet unknown_fields;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(unknown_fields.ParseFromString(data));
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(TextFormat::PrintUnknownFieldsToString(unknown_fields, &text));
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "44: \"abc\"\n"
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "44: \"def\"\n"
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "44: \"\"\n"
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "48 {\n"
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  1: 123\n"
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}\n",
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    text);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatTest, PrintMessageWithIndent) {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test adding an initial indent to printing.
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protobuf_unittest::TestAllTypes message;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_string("abc");
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_string("def");
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_nested_message()->set_bb(123);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string text;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TextFormat::Printer printer;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer.SetInitialIndentLevel(1);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(printer.PrintToString(message, &text));
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  repeated_string: \"abc\"\n"
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  repeated_string: \"def\"\n"
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  repeated_nested_message {\n"
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    bb: 123\n"
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  }\n",
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    text);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatTest, PrintMessageSingleLine) {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test printing a message on a single line.
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protobuf_unittest::TestAllTypes message;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_string("abc");
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_string("def");
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_nested_message()->set_bb(123);
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string text;
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TextFormat::Printer printer;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer.SetInitialIndentLevel(1);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer.SetSingleLineMode(true);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(printer.PrintToString(message, &text));
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  repeated_string: \"abc\" repeated_string: \"def\" "
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_nested_message { bb: 123 } ",
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    text);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
342ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(TextFormatTest, PrintBufferTooSmall) {
343ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Test printing a message to a buffer that is too small.
344ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
345ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  protobuf_unittest::TestAllTypes message;
346ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
347ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  message.add_repeated_string("abc");
348ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  message.add_repeated_string("def");
349ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
350ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  char buffer[1] = "";
351ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  io::ArrayOutputStream output_stream(buffer, 1);
352ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_FALSE(TextFormat::Print(message, &output_stream));
353ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(buffer[0], 'r');
354ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(output_stream.ByteCount(), 1);
355ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
356ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatTest, ParseBasic) {
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io::ArrayInputStream input_stream(proto_debug_string_.data(),
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    proto_debug_string_.size());
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TextFormat::Parse(&input_stream, &proto_);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::ExpectAllFieldsSet(proto_);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatExtensionsTest, ParseExtensions) {
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io::ArrayInputStream input_stream(proto_debug_string_.data(),
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    proto_debug_string_.size());
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TextFormat::Parse(&input_stream, &proto_);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::ExpectAllExtensionsSet(proto_);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatTest, ParseEnumFieldFromNumber) {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a parse string with a numerical value for an enum field.
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string parse_string = strings::Substitute("optional_nested_enum: $0",
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            unittest::TestAllTypes::BAZ);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto_));
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(proto_.has_optional_nested_enum());
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(unittest::TestAllTypes::BAZ, proto_.optional_nested_enum());
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatTest, ParseEnumFieldFromNegativeNumber) {
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_LT(unittest::SPARSE_E, 0);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string parse_string = strings::Substitute("sparse_enum: $0",
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            unittest::SPARSE_E);
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::SparseEnumMessage proto;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto));
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(proto.has_sparse_enum());
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(unittest::SPARSE_E, proto.sparse_enum());
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatTest, ParseStringEscape) {
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a parse string with escpaed characters in it.
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string parse_string = "optional_string: "
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      + kEscapeTestStringEscaped
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      + "\n";
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io::ArrayInputStream input_stream(parse_string.data(),
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    parse_string.size());
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TextFormat::Parse(&input_stream, &proto_);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Compare.
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kEscapeTestString, proto_.optional_string());
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatTest, ParseConcatenatedString) {
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a parse string with multiple parts on one line.
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string parse_string = "optional_string: \"foo\" \"bar\"\n";
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io::ArrayInputStream input_stream1(parse_string.data(),
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    parse_string.size());
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TextFormat::Parse(&input_stream1, &proto_);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Compare.
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foobar", proto_.optional_string());
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a parse string with multiple parts on seperate lines.
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parse_string = "optional_string: \"foo\"\n"
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 "\"bar\"\n";
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io::ArrayInputStream input_stream2(parse_string.data(),
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    parse_string.size());
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TextFormat::Parse(&input_stream2, &proto_);
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Compare.
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foobar", proto_.optional_string());
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatTest, ParseFloatWithSuffix) {
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that we can parse a floating-point value with 'f' appended to the
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // end.  This is needed for backwards-compatibility with proto1.
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Have it parse a float with the 'f' suffix.
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string parse_string = "optional_float: 1.0f\n";
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io::ArrayInputStream input_stream(parse_string.data(),
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    parse_string.size());
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TextFormat::Parse(&input_stream, &proto_);
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Compare.
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1.0, proto_.optional_float());
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatTest, ParseShortRepeatedForm) {
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string parse_string =
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Mixed short-form and long-form are simply concatenated.
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "repeated_int32: 1\n"
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "repeated_int32: [456, 789]\n"
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "repeated_nested_enum: [  FOO ,BAR, # comment\n"
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "                         3]\n"
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Note that while the printer won't print repeated strings in short-form,
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // the parser will accept them.
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "repeated_string: [ \"foo\", 'bar' ]\n";
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(TextFormat::ParseFromString(parse_string, &proto_));
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3, proto_.repeated_int32_size());
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, proto_.repeated_int32(0));
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(456, proto_.repeated_int32(1));
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(789, proto_.repeated_int32(2));
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3, proto_.repeated_nested_enum_size());
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(unittest::TestAllTypes::FOO, proto_.repeated_nested_enum(0));
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(unittest::TestAllTypes::BAR, proto_.repeated_nested_enum(1));
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(unittest::TestAllTypes::BAZ, proto_.repeated_nested_enum(2));
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, proto_.repeated_string_size());
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foo", proto_.repeated_string(0));
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("bar", proto_.repeated_string(1));
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatTest, Comments) {
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that comments are ignored.
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string parse_string = "optional_int32: 1  # a comment\n"
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        "optional_int64: 2  # another comment";
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io::ArrayInputStream input_stream(parse_string.data(),
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    parse_string.size());
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TextFormat::Parse(&input_stream, &proto_);
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Compare.
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, proto_.optional_int32());
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, proto_.optional_int64());
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatTest, OptionalColon) {
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that we can place a ':' after the field name of a nested message,
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // even though we don't have to.
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string parse_string = "optional_nested_message: { bb: 1}\n";
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io::ArrayInputStream input_stream(parse_string.data(),
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    parse_string.size());
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TextFormat::Parse(&input_stream, &proto_);
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Compare.
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(proto_.has_optional_nested_message());
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, proto_.optional_nested_message().bb());
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Some platforms (e.g. Windows) insist on padding the exponent to three
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// digits when one or two would be just fine.
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static string RemoveRedundantZeros(string text) {
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  text = StringReplace(text, "e+0", "e+", true);
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  text = StringReplace(text, "e-0", "e-", true);
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return text;
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatTest, PrintExotic) {
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestAllTypes message;
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note:  In C, a negative integer literal is actually the unary negation
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   operator being applied to a positive integer literal, and
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   9223372036854775808 is outside the range of int64.  However, it is not
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   outside the range of uint64.  Confusingly, this means that everything
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   works if we make the literal unsigned, even though we are negating it.
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_int64(-GOOGLE_ULONGLONG(9223372036854775808));
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_uint64(GOOGLE_ULONGLONG(18446744073709551615));
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(123.456);
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.23e21);
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.23e-18);
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(std::numeric_limits<double>::infinity());
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(-std::numeric_limits<double>::infinity());
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(std::numeric_limits<double>::quiet_NaN());
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_string(string("\000\001\a\b\f\n\r\t\v\\\'\"", 12));
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fun story:  We used to use 1.23e22 instead of 1.23e21 above, but this
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   seemed to trigger an odd case on MinGW/GCC 3.4.5 where GCC's parsing of
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   the value differed from strtod()'s parsing.  That is to say, the
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   following assertion fails on MinGW:
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     assert(1.23e22 == strtod("1.23e22", NULL));
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   As a result, SimpleDtoa() would print the value as
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   "1.2300000000000001e+22" to make sure strtod() produce the exact same
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   result.  Our goal is to test runtime parsing, not compile-time parsing,
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   so this wasn't our problem.  It was found that using 1.23e21 did not
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   have this problem, so we switched to that instead.
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_int64: -9223372036854775808\n"
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_uint64: 18446744073709551615\n"
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 123.456\n"
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.23e+21\n"
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.23e-18\n"
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: inf\n"
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: -inf\n"
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: nan\n"
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_string: \"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\'\\\"\"\n",
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RemoveRedundantZeros(message.DebugString()));
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatTest, PrintFloatPrecision) {
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestAllTypes message;
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_float(1.2);
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_float(1.23);
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_float(1.234);
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_float(1.2345);
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_float(1.23456);
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_float(1.2e10);
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_float(1.23e10);
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_float(1.234e10);
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_float(1.2345e10);
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_float(1.23456e10);
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.2);
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.23);
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.234);
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.2345);
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.23456);
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.234567);
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.2345678);
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.23456789);
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.234567898);
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.2345678987);
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.23456789876);
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.234567898765);
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.2345678987654);
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.23456789876543);
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.2e100);
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.23e100);
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.234e100);
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.2345e100);
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.23456e100);
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.234567e100);
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.2345678e100);
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.23456789e100);
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.234567898e100);
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.2345678987e100);
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.23456789876e100);
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.234567898765e100);
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.2345678987654e100);
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.add_repeated_double(1.23456789876543e100);
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_float: 1.2\n"
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_float: 1.23\n"
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_float: 1.234\n"
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_float: 1.2345\n"
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_float: 1.23456\n"
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_float: 1.2e+10\n"
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_float: 1.23e+10\n"
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_float: 1.234e+10\n"
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_float: 1.2345e+10\n"
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_float: 1.23456e+10\n"
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.2\n"
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.23\n"
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.234\n"
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.2345\n"
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.23456\n"
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.234567\n"
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.2345678\n"
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.23456789\n"
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.234567898\n"
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.2345678987\n"
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.23456789876\n"
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.234567898765\n"
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.2345678987654\n"
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.23456789876543\n"
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.2e+100\n"
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.23e+100\n"
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.234e+100\n"
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.2345e+100\n"
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.23456e+100\n"
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.234567e+100\n"
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.2345678e+100\n"
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.23456789e+100\n"
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.234567898e+100\n"
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.2345678987e+100\n"
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.23456789876e+100\n"
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.234567898765e+100\n"
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.2345678987654e+100\n"
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.23456789876543e+100\n",
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RemoveRedundantZeros(message.DebugString()));
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatTest, AllowPartial) {
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestRequired message;
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TextFormat::Parser parser;
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parser.AllowPartialMessage(true);
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.ParseFromString("a: 1", &message));
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, message.a());
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(message.has_b());
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(message.has_c());
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatTest, ParseExotic) {
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestAllTypes message;
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(TextFormat::ParseFromString(
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_int32: -1\n"
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_int32: -2147483648\n"
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_int64: -1\n"
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_int64: -9223372036854775808\n"
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_uint32: 4294967295\n"
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_uint32: 2147483648\n"
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_uint64: 18446744073709551615\n"
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_uint64: 9223372036854775808\n"
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 123.0\n"
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 123.5\n"
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 0.125\n"
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.23E17\n"
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.235E+22\n"
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 1.235e-18\n"
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: 123.456789\n"
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: inf\n"
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: Infinity\n"
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: -inf\n"
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: -Infinity\n"
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: nan\n"
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_double: NaN\n"
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "repeated_string: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\"\n",
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    &message));
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, message.repeated_int32_size());
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, message.repeated_int32(0));
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note:  In C, a negative integer literal is actually the unary negation
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   operator being applied to a positive integer literal, and 2147483648 is
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   outside the range of int32.  However, it is not outside the range of
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   uint32.  Confusingly, this means that everything works if we make the
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   literal unsigned, even though we are negating it.
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-2147483648u, message.repeated_int32(1));
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, message.repeated_int64_size());
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, message.repeated_int64(0));
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note:  In C, a negative integer literal is actually the unary negation
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   operator being applied to a positive integer literal, and
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   9223372036854775808 is outside the range of int64.  However, it is not
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   outside the range of uint64.  Confusingly, this means that everything
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   works if we make the literal unsigned, even though we are negating it.
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-GOOGLE_ULONGLONG(9223372036854775808), message.repeated_int64(1));
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, message.repeated_uint32_size());
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4294967295u, message.repeated_uint32(0));
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2147483648u, message.repeated_uint32(1));
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, message.repeated_uint64_size());
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GOOGLE_ULONGLONG(18446744073709551615), message.repeated_uint64(0));
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GOOGLE_ULONGLONG(9223372036854775808), message.repeated_uint64(1));
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(13, message.repeated_double_size());
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(123.0     , message.repeated_double(0));
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(123.5     , message.repeated_double(1));
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0.125     , message.repeated_double(2));
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1.23E17   , message.repeated_double(3));
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1.235E22  , message.repeated_double(4));
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1.235E-18 , message.repeated_double(5));
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(123.456789, message.repeated_double(6));
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message.repeated_double(7), numeric_limits<double>::infinity());
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message.repeated_double(8), numeric_limits<double>::infinity());
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message.repeated_double(9), -numeric_limits<double>::infinity());
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message.repeated_double(10), -numeric_limits<double>::infinity());
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(IsNaN(message.repeated_double(11)));
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(IsNaN(message.repeated_double(12)));
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note:  Since these string literals have \0's in them, we must explicitly
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   pass their sizes to string's constructor.
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, message.repeated_string_size());
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(string("\000\001\a\b\f\n\r\t\v\\\'\"", 12),
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            message.repeated_string(0));
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TextFormatParserTest : public testing::Test {
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ExpectFailure(const string& input, const string& message, int line,
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     int col) {
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<unittest::TestAllTypes> proto(new unittest::TestAllTypes);
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExpectFailure(input, message, line, col, proto.get());
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ExpectFailure(const string& input, const string& message, int line,
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     int col, Message* proto) {
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExpectMessage(input, message, line, col, proto, false);
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ExpectMessage(const string& input, const string& message, int line,
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     int col, Message* proto, bool expected_result) {
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TextFormat::Parser parser;
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockErrorCollector error_collector;
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parser.RecordErrorsTo(&error_collector);
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(parser.ParseFromString(input, proto), expected_result);
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(SimpleItoa(line) + ":" + SimpleItoa(col) + ": " + message + "\n",
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              error_collector.text_);
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
746ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  void ExpectSuccessAndTree(const string& input, Message* proto,
747ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                            TextFormat::ParseInfoTree* info_tree) {
748ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    TextFormat::Parser parser;
749ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    MockErrorCollector error_collector;
750ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    parser.RecordErrorsTo(&error_collector);
751ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    parser.WriteLocationsTo(info_tree);
752ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
753ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    EXPECT_TRUE(parser.ParseFromString(input, proto));
754ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
755ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
756ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  void ExpectLocation(TextFormat::ParseInfoTree* tree,
757ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                      const Descriptor* d, const string& field_name,
758ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                      int index, int line, int column) {
759ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    TextFormat::ParseLocation location = tree->GetLocation(
760ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        d->FindFieldByName(field_name), index);
761ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    EXPECT_EQ(line, location.line);
762ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    EXPECT_EQ(column, location.column);
763ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
764ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An error collector which simply concatenates all its errors into a big
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // block of text which can be checked.
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class MockErrorCollector : public io::ErrorCollector {
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockErrorCollector() {}
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~MockErrorCollector() {}
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string text_;
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // implements ErrorCollector -------------------------------------
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void AddError(int line, int column, const string& message) {
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      strings::SubstituteAndAppend(&text_, "$0:$1: $2\n",
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   line + 1, column + 1, message);
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void AddWarning(int line, int column, const string& message) {
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AddError(line, column, "WARNING:" + message);
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
786ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(TextFormatParserTest, ParseInfoTreeBuilding) {
787ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  scoped_ptr<unittest::TestAllTypes> message(new unittest::TestAllTypes);
788ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const Descriptor* d = message->GetDescriptor();
789ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
790ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  string stringData =
791ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "optional_int32: 1\n"
792ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "optional_int64: 2\n"
793ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "  optional_double: 2.4\n"
794ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "repeated_int32: 5\n"
795ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "repeated_int32: 10\n"
796ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "optional_nested_message <\n"
797ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "  bb: 78\n"
798ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      ">\n"
799ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "repeated_nested_message <\n"
800ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "  bb: 79\n"
801ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      ">\n"
802ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "repeated_nested_message <\n"
803ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "  bb: 80\n"
804ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      ">";
805ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
806ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
807ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  TextFormat::ParseInfoTree tree;
808ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ExpectSuccessAndTree(stringData, message.get(), &tree);
809ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
810ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Verify that the tree has the correct positions.
811ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ExpectLocation(&tree, d, "optional_int32", -1, 0, 0);
812ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ExpectLocation(&tree, d, "optional_int64", -1, 1, 0);
813ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ExpectLocation(&tree, d, "optional_double", -1, 2, 2);
814ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
815ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ExpectLocation(&tree, d, "repeated_int32", 0, 3, 0);
816ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ExpectLocation(&tree, d, "repeated_int32", 1, 4, 0);
817ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
818ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ExpectLocation(&tree, d, "optional_nested_message", -1, 5, 0);
819ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ExpectLocation(&tree, d, "repeated_nested_message", 0, 8, 0);
820ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ExpectLocation(&tree, d, "repeated_nested_message", 1, 11, 0);
821ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
822ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Check for fields not set. For an invalid field, the location returned
823ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // should be -1, -1.
824ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ExpectLocation(&tree, d, "repeated_int64", 0, -1, -1);
825ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ExpectLocation(&tree, d, "repeated_int32", 6, -1, -1);
826ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ExpectLocation(&tree, d, "some_unknown_field", -1, -1, -1);
827ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
828ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Verify inside the nested message.
829ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const FieldDescriptor* nested_field =
830ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      d->FindFieldByName("optional_nested_message");
831ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
832ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  TextFormat::ParseInfoTree* nested_tree =
833ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      tree.GetTreeForNested(nested_field, -1);
834ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 6, 2);
835ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
836ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Verify inside another nested message.
837ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  nested_field = d->FindFieldByName("repeated_nested_message");
838ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  nested_tree = tree.GetTreeForNested(nested_field, 0);
839ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 9, 2);
840ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
841ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  nested_tree = tree.GetTreeForNested(nested_field, 1);
842ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 12, 2);
843ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
844ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Verify a NULL tree for an unknown nested field.
845ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  TextFormat::ParseInfoTree* unknown_nested_tree =
846ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      tree.GetTreeForNested(nested_field, 2);
847ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
848ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(NULL, unknown_nested_tree);
849ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
850ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatParserTest, ParseFieldValueFromString) {
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<unittest::TestAllTypes> message(new unittest::TestAllTypes);
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* d = message->GetDescriptor();
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EXPECT_FIELD(name, value, valuestring) \
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    valuestring, d->FindFieldByName("optional_" #name), message.get())); \
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(value, message->optional_##name()); \
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message->has_optional_##name());
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#define EXPECT_BOOL_FIELD(name, value, valuestring) \
8623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
8633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    valuestring, d->FindFieldByName("optional_" #name), message.get())); \
8643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(message->optional_##name() == value); \
8653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(message->has_optional_##name());
8663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EXPECT_FLOAT_FIELD(name, value, valuestring) \
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    valuestring, d->FindFieldByName("optional_" #name), message.get())); \
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FLOAT_EQ(value, message->optional_##name()); \
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message->has_optional_##name());
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EXPECT_DOUBLE_FIELD(name, value, valuestring) \
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    valuestring, d->FindFieldByName("optional_" #name), message.get())); \
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_DOUBLE_EQ(value, message->optional_##name()); \
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message->has_optional_##name());
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EXPECT_INVALID(name, valuestring) \
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(TextFormat::ParseFieldValueFromString( \
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    valuestring, d->FindFieldByName("optional_" #name), message.get()));
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // int32
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FIELD(int32, 1, "1");
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FIELD(int32, -1, "-1");
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FIELD(int32, 0x1234, "0x1234");
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(int32, "a");
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(int32, "999999999999999999999999999999999999");
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(int32, "1,2");
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // int64
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FIELD(int64, 1, "1");
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FIELD(int64, -1, "-1");
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FIELD(int64, 0x1234567812345678LL, "0x1234567812345678");
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(int64, "a");
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(int64, "999999999999999999999999999999999999");
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(int64, "1,2");
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // uint64
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FIELD(uint64, 1, "1");
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FIELD(uint64, 0xf234567812345678ULL, "0xf234567812345678");
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(uint64, "-1");
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(uint64, "a");
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(uint64, "999999999999999999999999999999999999");
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(uint64, "1,2");
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fixed32
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FIELD(fixed32, 1, "1");
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FIELD(fixed32, 0x12345678, "0x12345678");
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(fixed32, "-1");
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(fixed32, "a");
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(fixed32, "999999999999999999999999999999999999");
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(fixed32, "1,2");
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fixed64
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FIELD(fixed64, 1, "1");
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FIELD(fixed64, 0x1234567812345678ULL, "0x1234567812345678");
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(fixed64, "-1");
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(fixed64, "a");
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(fixed64, "999999999999999999999999999999999999");
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(fixed64, "1,2");
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bool
9243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_BOOL_FIELD(bool, true, "true");
9253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_BOOL_FIELD(bool, false, "false");
9263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_BOOL_FIELD(bool, true, "1");
9273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_BOOL_FIELD(bool, true, "t");
9283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_BOOL_FIELD(bool, false, "0");
9293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_BOOL_FIELD(bool, false, "f");
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(bool, "2");
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(bool, "-0");
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(bool, "on");
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(bool, "a");
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(bool, "True");
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // float
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FIELD(float, 1, "1");
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FLOAT_FIELD(float, 1.5, "1.5");
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FLOAT_FIELD(float, 1.5e3, "1.5e3");
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FLOAT_FIELD(float, -4.55, "-4.55");
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(float, "a");
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(float, "1,2");
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // double
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FIELD(double, 1, "1");
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FIELD(double, -1, "-1");
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_DOUBLE_FIELD(double, 2.3, "2.3");
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_DOUBLE_FIELD(double, 3e5, "3e5");
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(double, "a");
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(double, "1,2");
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // string
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FIELD(string, "hello", "\"hello\"");
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FIELD(string, "-1.87", "'-1.87'");
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(string, "hello");  // without quote for value
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // enum
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAR, "BAR");
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAZ,
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SimpleItoa(unittest::TestAllTypes::BAZ));
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(nested_enum, "FOOBAR");
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // message
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(TextFormat::ParseFieldValueFromString(
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "<bb:12>", d->FindFieldByName("optional_nested_message"), message.get()));
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(12, message->optional_nested_message().bb()); \
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message->has_optional_nested_message());
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_INVALID(nested_message, "any");
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef EXPECT_FIELD
9713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#undef EXPECT_BOOL_FIELD
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef EXPECT_FLOAT_FIELD
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef EXPECT_DOUBLE_FIELD
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef EXPECT_INVALID
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatParserTest, InvalidToken) {
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_bool: true\n-5\n", "Expected identifier.",
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                2, 1);
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_bool: true!\n", "Expected identifier.", 1, 20);
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("\"some string\"", "Expected identifier.", 1, 1);
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatParserTest, InvalidFieldName) {
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure(
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "invalid_field: somevalue\n",
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\"invalid_field\".",
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1, 14);
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatParserTest, InvalidCapitalization) {
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We require that group names be exactly as they appear in the .proto.
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure(
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "optionalgroup {\na: 15\n}\n",
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\"optionalgroup\".",
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1, 15);
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure(
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "OPTIONALgroup {\na: 15\n}\n",
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\"OPTIONALgroup\".",
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1, 15);
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure(
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Optional_Double: 10.0\n",
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\"Optional_Double\".",
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1, 16);
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatParserTest, InvalidFieldValues) {
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invalid values for a double/float field.
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_double: \"hello\"\n", "Expected double.", 1, 18);
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_double: true\n", "Expected double.", 1, 18);
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_double: !\n", "Expected double.", 1, 18);
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_double {\n  \n}\n", "Expected \":\", found \"{\".",
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                1, 17);
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invalid values for a signed integer field.
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_int32: \"hello\"\n", "Expected integer.", 1, 17);
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_int32: true\n", "Expected integer.", 1, 17);
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_int32: 4.5\n", "Expected integer.", 1, 17);
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_int32: !\n", "Expected integer.", 1, 17);
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_int32 {\n \n}\n", "Expected \":\", found \"{\".",
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                1, 16);
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_int32: 0x80000000\n",
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Integer out of range.", 1, 17);
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_int64: 0x8000000000000000\n",
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Integer out of range.", 1, 17);
1032ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ExpectFailure("optional_int32: -0x80000001\n",
1033ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                "Integer out of range.", 1, 18);
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_int64: -0x8000000000000001\n",
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Integer out of range.", 1, 18);
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invalid values for an unsigned integer field.
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_uint64: \"hello\"\n", "Expected integer.", 1, 18);
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_uint64: true\n", "Expected integer.", 1, 18);
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_uint64: 4.5\n", "Expected integer.", 1, 18);
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_uint64: -5\n", "Expected integer.", 1, 18);
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_uint64: !\n", "Expected integer.", 1, 18);
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_uint64 {\n \n}\n", "Expected \":\", found \"{\".",
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                1, 17);
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_uint32: 0x100000000\n",
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Integer out of range.", 1, 18);
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_uint64: 0x10000000000000000\n",
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Integer out of range.", 1, 18);
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invalid values for a boolean field.
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_bool: \"hello\"\n", "Expected identifier.", 1, 16);
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_bool: 5\n", "Integer out of range.", 1, 16);
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_bool: -7.5\n", "Expected identifier.", 1, 16);
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_bool: !\n", "Expected identifier.", 1, 16);
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure(
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "optional_bool: meh\n",
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Invalid value for boolean field \"optional_bool\". Value: \"meh\".",
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      2, 1);
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_bool {\n \n}\n", "Expected \":\", found \"{\".",
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                1, 15);
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invalid values for a string field.
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_string: true\n", "Expected string.", 1, 18);
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_string: 5\n", "Expected string.", 1, 18);
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_string: -7.5\n", "Expected string.", 1, 18);
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_string: !\n", "Expected string.", 1, 18);
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_string {\n \n}\n", "Expected \":\", found \"{\".",
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                1, 17);
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invalid values for an enumeration field.
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_nested_enum: \"hello\"\n",
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Expected integer or identifier.", 1, 23);
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Valid token, but enum value is not defined.
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_nested_enum: 5\n",
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Unknown enumeration value of \"5\" for field "
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "\"optional_nested_enum\".", 2, 1);
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We consume the negative sign, so the error position starts one character
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // later.
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_nested_enum: -7.5\n", "Expected integer.", 1, 24);
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_nested_enum: !\n",
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Expected integer or identifier.", 1, 23);
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure(
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "optional_nested_enum: grah\n",
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Unknown enumeration value of \"grah\" for field "
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\"optional_nested_enum\".", 2, 1);
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure(
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "optional_nested_enum {\n \n}\n",
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Expected \":\", found \"{\".", 1, 22);
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatParserTest, MessageDelimeters) {
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Non-matching delimeters.
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("OptionalGroup <\n \n}\n", "Expected \">\", found \"}\".",
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                3, 1);
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invalid delimeters.
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("OptionalGroup [\n \n]\n", "Expected \"{\", found \"[\".",
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                1, 15);
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unending message.
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("optional_nested_message {\n \nbb: 118\n",
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Expected identifier.",
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                4, 1);
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatParserTest, UnknownExtension) {
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Non-matching delimeters.
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("[blahblah]: 123",
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Extension \"blahblah\" is not defined or is not an "
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "extension of \"protobuf_unittest.TestAllTypes\".",
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                1, 11);
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatParserTest, MissingRequired) {
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestRequired message;
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("a: 1",
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Message missing required fields: b, c",
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                0, 1, &message);
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatParserTest, ParseDuplicateRequired) {
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestRequired message;
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("a: 1 b: 2 c: 3 a: 1",
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Non-repeated field \"a\" is specified multiple times.",
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                1, 17, &message);
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatParserTest, ParseDuplicateOptional) {
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::ForeignMessage message;
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectFailure("c: 1 c: 2",
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Non-repeated field \"c\" is specified multiple times.",
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                1, 7, &message);
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatParserTest, MergeDuplicateRequired) {
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestRequired message;
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TextFormat::Parser parser;
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.MergeFromString("a: 1 b: 2 c: 3 a: 4", &message));
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4, message.a());
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatParserTest, MergeDuplicateOptional) {
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::ForeignMessage message;
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TextFormat::Parser parser;
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.MergeFromString("c: 1 c: 2", &message));
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, message.c());
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatParserTest, ExplicitDelimiters) {
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestRequired message;
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(TextFormat::ParseFromString("a:1,b:2;c:3", &message));
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, message.a());
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, message.b());
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, message.c());
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatParserTest, PrintErrorsToStderr) {
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<string> errors;
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedMemoryLog log;
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unittest::TestAllTypes proto;
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(TextFormat::ParseFromString("no_such_field: 1", &proto));
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    errors = log.GetMessages(ERROR);
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, errors.size());
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Error parsing text-format protobuf_unittest.TestAllTypes: "
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "1:14: Message type \"protobuf_unittest.TestAllTypes\" has no field "
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "named \"no_such_field\".",
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            errors[0]);
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatParserTest, FailsOnTokenizationError) {
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<string> errors;
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedMemoryLog log;
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unittest::TestAllTypes proto;
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(TextFormat::ParseFromString("\020", &proto));
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    errors = log.GetMessages(ERROR);
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, errors.size());
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Error parsing text-format protobuf_unittest.TestAllTypes: "
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "1:1: Invalid control characters encountered in text.",
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            errors[0]);
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatParserTest, ParseDeprecatedField) {
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestDeprecatedFields message;
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectMessage("deprecated_int32: 42",
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "WARNING:text format contains deprecated field "
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "\"deprecated_int32\"", 1, 21, &message, true);
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TextFormatMessageSetTest : public testing::Test {
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char proto_debug_string_[];
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char TextFormatMessageSetTest::proto_debug_string_[] =
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"message_set {\n"
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"  [protobuf_unittest.TestMessageSetExtension1] {\n"
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"    i: 23\n"
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"  }\n"
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"  [protobuf_unittest.TestMessageSetExtension2] {\n"
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"    str: \"foo\"\n"
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"  }\n"
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"}\n";
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatMessageSetTest, Serialize) {
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protobuf_unittest::TestMessageSetContainer proto;
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protobuf_unittest::TestMessageSetExtension1* item_a =
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    proto.mutable_message_set()->MutableExtension(
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      protobuf_unittest::TestMessageSetExtension1::message_set_extension);
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  item_a->set_i(23);
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protobuf_unittest::TestMessageSetExtension2* item_b =
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    proto.mutable_message_set()->MutableExtension(
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      protobuf_unittest::TestMessageSetExtension2::message_set_extension);
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  item_b->set_str("foo");
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(proto_debug_string_, proto.DebugString());
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TextFormatMessageSetTest, Deserialize) {
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protobuf_unittest::TestMessageSetContainer proto;
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(TextFormat::ParseFromString(proto_debug_string_, &proto));
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(23, proto.message_set().GetExtension(
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    protobuf_unittest::TestMessageSetExtension1::message_set_extension).i());
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foo", proto.message_set().GetExtension(
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    protobuf_unittest::TestMessageSetExtension2::message_set_extension).str());
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that these are the only entries present.
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<const FieldDescriptor*> descriptors;
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proto.message_set().GetReflection()->ListFields(
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    proto.message_set(), &descriptors);
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, descriptors.size());
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace text_format_unittest
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace protobuf
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace google
1249