text_format_unittest.cc revision d0332953cda33fb4f8e24ebff9c49159b69c43d6
16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Protocol Buffers - Google's data interchange format 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Copyright 2008 Google Inc. All rights reserved. 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// http://code.google.com/p/protobuf/ 46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// 56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Redistribution and use in source and binary forms, with or without 66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// modification, are permitted provided that the following conditions are 76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// met: 86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// * Redistributions of source code must retain the above copyright 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// notice, this list of conditions and the following disclaimer. 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// * Redistributions in binary form must reproduce the above 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// copyright notice, this list of conditions and the following disclaimer 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// in the documentation and/or other materials provided with the 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// distribution. 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// * Neither the name of Google Inc. nor the names of its 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// contributors may be used to endorse or promote products derived from 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// this software without specific prior written permission. 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Author: jschorr@google.com (Joseph Schorr) 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Based on original Protocol Buffers design by 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Sanjay Ghemawat, Jeff Dean, and others. 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <math.h> 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <stdlib.h> 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <limits> 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <google/protobuf/text_format.h> 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <google/protobuf/io/zero_copy_stream_impl.h> 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <google/protobuf/io/tokenizer.h> 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <google/protobuf/unittest.pb.h> 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <google/protobuf/unittest_mset.pb.h> 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <google/protobuf/test_util.h> 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <google/protobuf/stubs/common.h> 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <google/protobuf/testing/file.h> 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <google/protobuf/testing/googletest.h> 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <gtest/gtest.h> 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <google/protobuf/stubs/strutil.h> 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <google/protobuf/stubs/substitute.h> 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgnamespace google { 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgnamespace protobuf { 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Can't use an anonymous namespace here due to brokenness of Tru64 compiler. 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgnamespace text_format_unittest { 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orginline bool IsNaN(double value) { 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // NaN is never equal to anything, even itself. 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return value != value; 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// A basic string with different escapable characters for testing. 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst string kEscapeTestString = 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "\"A string with ' characters \n and \r newlines and \t tabs and \001 " 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "slashes \\ and multiple spaces"; 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// A representation of the above string with all the characters escaped. 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst string kEscapeTestStringEscaped = 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "\"\\\"A string with \\' characters \\n and \\r newlines " 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "and \\t tabs and \\001 slashes \\\\ and multiple spaces\""; 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgclass TextFormatTest : public testing::Test { 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public: 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org static void SetUpTestCase() { 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org File::ReadFileToStringOrDie( 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TestSourceDir() 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org + "/google/protobuf/testdata/text_format_unittest_data.txt", 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &static_proto_debug_string_); 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TextFormatTest() : proto_debug_string_(static_proto_debug_string_) {} 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org protected: 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Debug string read from text_format_unittest_data.txt. 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const string proto_debug_string_; 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org unittest::TestAllTypes proto_; 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org private: 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org static string static_proto_debug_string_; 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstring TextFormatTest::static_proto_debug_string_; 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgclass TextFormatExtensionsTest : public testing::Test { 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org public: 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org static void SetUpTestCase() { 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org File::ReadFileToStringOrDie( 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TestSourceDir() 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org + "/google/protobuf/testdata/" 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "text_format_unittest_extensions_data.txt", 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &static_proto_debug_string_); 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TextFormatExtensionsTest() 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org : proto_debug_string_(static_proto_debug_string_) {} 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org protected: 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Debug string read from text_format_unittest_data.txt. 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const string proto_debug_string_; 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org unittest::TestAllExtensions proto_; 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org private: 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org static string static_proto_debug_string_; 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstring TextFormatExtensionsTest::static_proto_debug_string_; 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTEST_F(TextFormatTest, Basic) { 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TestUtil::SetAllFields(&proto_); 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org EXPECT_EQ(proto_debug_string_, proto_.DebugString()); 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTEST_F(TextFormatExtensionsTest, Extensions) { 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TestUtil::SetAllExtensions(&proto_); 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org EXPECT_EQ(proto_debug_string_, proto_.DebugString()); 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTEST_F(TextFormatTest, ShortDebugString) { 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org proto_.set_optional_int32(1); 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org proto_.set_optional_string("hello"); 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org proto_.mutable_optional_nested_message()->set_bb(2); 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org proto_.mutable_optional_foreign_message(); 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org EXPECT_EQ("optional_int32: 1 optional_string: \"hello\" " 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "optional_nested_message { bb: 2 } " 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "optional_foreign_message { }", 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org proto_.ShortDebugString()); 1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTEST_F(TextFormatTest, ShortPrimitiveRepeateds) { 1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org proto_.set_optional_int32(123); 1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org proto_.add_repeated_int32(456); 1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org proto_.add_repeated_int32(789); 1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org proto_.add_repeated_string("foo"); 1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org proto_.add_repeated_string("bar"); 1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org proto_.add_repeated_nested_message()->set_bb(2); 1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org proto_.add_repeated_nested_message()->set_bb(3); 1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org proto_.add_repeated_nested_enum(unittest::TestAllTypes::FOO); 1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org proto_.add_repeated_nested_enum(unittest::TestAllTypes::BAR); 1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TextFormat::Printer printer; 1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org printer.SetUseShortRepeatedPrimitives(true); 1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org string text; 1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org printer.PrintToString(proto_, &text); 1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org EXPECT_EQ("optional_int32: 123\n" 1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "repeated_int32: [456, 789]\n" 1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "repeated_string: \"foo\"\n" 1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "repeated_string: \"bar\"\n" 1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "repeated_nested_message {\n bb: 2\n}\n" 1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "repeated_nested_message {\n bb: 3\n}\n" 1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "repeated_nested_enum: [FOO, BAR]\n", 1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org text); 1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Try in single-line mode. 1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org printer.SetSingleLineMode(true); 1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org printer.PrintToString(proto_, &text); 1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org EXPECT_EQ("optional_int32: 123 " 1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "repeated_int32: [456, 789] " 1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "repeated_string: \"foo\" " 1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "repeated_string: \"bar\" " 1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "repeated_nested_message { bb: 2 } " 1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "repeated_nested_message { bb: 3 } " 1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "repeated_nested_enum: [FOO, BAR] ", 1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org text); 1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTEST_F(TextFormatTest, StringEscape) { 1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Set the string value to test. 1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org proto_.set_optional_string(kEscapeTestString); 1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Get the DebugString from the proto. 1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org string debug_string = proto_.DebugString(); 1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org string utf8_debug_string = proto_.Utf8DebugString(); 1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Hardcode a correct value to test against. 1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org string correct_string = "optional_string: " 1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org + kEscapeTestStringEscaped 1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org + "\n"; 1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Compare. 1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org EXPECT_EQ(correct_string, debug_string); 1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // UTF-8 string is the same as non-UTF-8 because 1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // the protocol buffer contains no UTF-8 text. 1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org EXPECT_EQ(correct_string, utf8_debug_string); 1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org string expected_short_debug_string = "optional_string: " 2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org + kEscapeTestStringEscaped; 2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org EXPECT_EQ(expected_short_debug_string, proto_.ShortDebugString()); 203} 204 205TEST_F(TextFormatTest, Utf8DebugString) { 206 // Set the string value to test. 207 proto_.set_optional_string("\350\260\267\346\255\214"); 208 209 // Get the DebugString from the proto. 210 string debug_string = proto_.DebugString(); 211 string utf8_debug_string = proto_.Utf8DebugString(); 212 213 // Hardcode a correct value to test against. 214 string correct_utf8_string = "optional_string: " 215 "\"\350\260\267\346\255\214\"" 216 "\n"; 217 string correct_string = "optional_string: " 218 "\"\\350\\260\\267\\346\\255\\214\"" 219 "\n"; 220 221 // Compare. 222 EXPECT_EQ(correct_utf8_string, utf8_debug_string); 223 EXPECT_EQ(correct_string, debug_string); 224} 225 226TEST_F(TextFormatTest, PrintUnknownFields) { 227 // Test printing of unknown fields in a message. 228 229 unittest::TestEmptyMessage message; 230 UnknownFieldSet* unknown_fields = message.mutable_unknown_fields(); 231 232 unknown_fields->AddVarint(5, 1); 233 unknown_fields->AddFixed32(5, 2); 234 unknown_fields->AddFixed64(5, 3); 235 unknown_fields->AddLengthDelimited(5, "4"); 236 unknown_fields->AddGroup(5)->AddVarint(10, 5); 237 238 unknown_fields->AddVarint(8, 1); 239 unknown_fields->AddVarint(8, 2); 240 unknown_fields->AddVarint(8, 3); 241 242 EXPECT_EQ( 243 "5: 1\n" 244 "5: 0x00000002\n" 245 "5: 0x0000000000000003\n" 246 "5: \"4\"\n" 247 "5 {\n" 248 " 10: 5\n" 249 "}\n" 250 "8: 1\n" 251 "8: 2\n" 252 "8: 3\n", 253 message.DebugString()); 254} 255 256TEST_F(TextFormatTest, PrintUnknownMessage) { 257 // Test heuristic printing of messages in an UnknownFieldSet. 258 259 protobuf_unittest::TestAllTypes message; 260 261 // Cases which should not be interpreted as sub-messages. 262 263 // 'a' is a valid FIXED64 tag, so for the string to be parseable as a message 264 // it should be followed by 8 bytes. Since this string only has two 265 // subsequent bytes, it should be treated as a string. 266 message.add_repeated_string("abc"); 267 268 // 'd' happens to be a valid ENDGROUP tag. So, 269 // UnknownFieldSet::MergeFromCodedStream() will successfully parse "def", but 270 // the ConsumedEntireMessage() check should fail. 271 message.add_repeated_string("def"); 272 273 // A zero-length string should never be interpreted as a message even though 274 // it is technically valid as one. 275 message.add_repeated_string(""); 276 277 // Case which should be interpreted as a sub-message. 278 279 // An actual nested message with content should always be interpreted as a 280 // nested message. 281 message.add_repeated_nested_message()->set_bb(123); 282 283 string data; 284 message.SerializeToString(&data); 285 286 string text; 287 UnknownFieldSet unknown_fields; 288 EXPECT_TRUE(unknown_fields.ParseFromString(data)); 289 EXPECT_TRUE(TextFormat::PrintUnknownFieldsToString(unknown_fields, &text)); 290 EXPECT_EQ( 291 "44: \"abc\"\n" 292 "44: \"def\"\n" 293 "44: \"\"\n" 294 "48 {\n" 295 " 1: 123\n" 296 "}\n", 297 text); 298} 299 300TEST_F(TextFormatTest, PrintMessageWithIndent) { 301 // Test adding an initial indent to printing. 302 303 protobuf_unittest::TestAllTypes message; 304 305 message.add_repeated_string("abc"); 306 message.add_repeated_string("def"); 307 message.add_repeated_nested_message()->set_bb(123); 308 309 string text; 310 TextFormat::Printer printer; 311 printer.SetInitialIndentLevel(1); 312 EXPECT_TRUE(printer.PrintToString(message, &text)); 313 EXPECT_EQ( 314 " repeated_string: \"abc\"\n" 315 " repeated_string: \"def\"\n" 316 " repeated_nested_message {\n" 317 " bb: 123\n" 318 " }\n", 319 text); 320} 321 322TEST_F(TextFormatTest, PrintMessageSingleLine) { 323 // Test printing a message on a single line. 324 325 protobuf_unittest::TestAllTypes message; 326 327 message.add_repeated_string("abc"); 328 message.add_repeated_string("def"); 329 message.add_repeated_nested_message()->set_bb(123); 330 331 string text; 332 TextFormat::Printer printer; 333 printer.SetInitialIndentLevel(1); 334 printer.SetSingleLineMode(true); 335 EXPECT_TRUE(printer.PrintToString(message, &text)); 336 EXPECT_EQ( 337 " repeated_string: \"abc\" repeated_string: \"def\" " 338 "repeated_nested_message { bb: 123 } ", 339 text); 340} 341 342TEST_F(TextFormatTest, ParseBasic) { 343 io::ArrayInputStream input_stream(proto_debug_string_.data(), 344 proto_debug_string_.size()); 345 TextFormat::Parse(&input_stream, &proto_); 346 TestUtil::ExpectAllFieldsSet(proto_); 347} 348 349TEST_F(TextFormatExtensionsTest, ParseExtensions) { 350 io::ArrayInputStream input_stream(proto_debug_string_.data(), 351 proto_debug_string_.size()); 352 TextFormat::Parse(&input_stream, &proto_); 353 TestUtil::ExpectAllExtensionsSet(proto_); 354} 355 356TEST_F(TextFormatTest, ParseStringEscape) { 357 // Create a parse string with escpaed characters in it. 358 string parse_string = "optional_string: " 359 + kEscapeTestStringEscaped 360 + "\n"; 361 362 io::ArrayInputStream input_stream(parse_string.data(), 363 parse_string.size()); 364 TextFormat::Parse(&input_stream, &proto_); 365 366 // Compare. 367 EXPECT_EQ(kEscapeTestString, proto_.optional_string()); 368} 369 370TEST_F(TextFormatTest, ParseConcatenatedString) { 371 // Create a parse string with multiple parts on one line. 372 string parse_string = "optional_string: \"foo\" \"bar\"\n"; 373 374 io::ArrayInputStream input_stream1(parse_string.data(), 375 parse_string.size()); 376 TextFormat::Parse(&input_stream1, &proto_); 377 378 // Compare. 379 EXPECT_EQ("foobar", proto_.optional_string()); 380 381 // Create a parse string with multiple parts on seperate lines. 382 parse_string = "optional_string: \"foo\"\n" 383 "\"bar\"\n"; 384 385 io::ArrayInputStream input_stream2(parse_string.data(), 386 parse_string.size()); 387 TextFormat::Parse(&input_stream2, &proto_); 388 389 // Compare. 390 EXPECT_EQ("foobar", proto_.optional_string()); 391} 392 393TEST_F(TextFormatTest, ParseFloatWithSuffix) { 394 // Test that we can parse a floating-point value with 'f' appended to the 395 // end. This is needed for backwards-compatibility with proto1. 396 397 // Have it parse a float with the 'f' suffix. 398 string parse_string = "optional_float: 1.0f\n"; 399 400 io::ArrayInputStream input_stream(parse_string.data(), 401 parse_string.size()); 402 403 TextFormat::Parse(&input_stream, &proto_); 404 405 // Compare. 406 EXPECT_EQ(1.0, proto_.optional_float()); 407} 408 409TEST_F(TextFormatTest, Comments) { 410 // Test that comments are ignored. 411 412 string parse_string = "optional_int32: 1 # a comment\n" 413 "optional_int64: 2 # another comment"; 414 415 io::ArrayInputStream input_stream(parse_string.data(), 416 parse_string.size()); 417 418 TextFormat::Parse(&input_stream, &proto_); 419 420 // Compare. 421 EXPECT_EQ(1, proto_.optional_int32()); 422 EXPECT_EQ(2, proto_.optional_int64()); 423} 424 425TEST_F(TextFormatTest, OptionalColon) { 426 // Test that we can place a ':' after the field name of a nested message, 427 // even though we don't have to. 428 429 string parse_string = "optional_nested_message: { bb: 1}\n"; 430 431 io::ArrayInputStream input_stream(parse_string.data(), 432 parse_string.size()); 433 434 TextFormat::Parse(&input_stream, &proto_); 435 436 // Compare. 437 EXPECT_TRUE(proto_.has_optional_nested_message()); 438 EXPECT_EQ(1, proto_.optional_nested_message().bb()); 439} 440 441// Some platforms (e.g. Windows) insist on padding the exponent to three 442// digits when one or two would be just fine. 443static string RemoveRedundantZeros(string text) { 444 text = StringReplace(text, "e+0", "e+", true); 445 text = StringReplace(text, "e-0", "e-", true); 446 return text; 447} 448 449TEST_F(TextFormatTest, PrintExotic) { 450 unittest::TestAllTypes message; 451 452 // Note: In C, a negative integer literal is actually the unary negation 453 // operator being applied to a positive integer literal, and 454 // 9223372036854775808 is outside the range of int64. However, it is not 455 // outside the range of uint64. Confusingly, this means that everything 456 // works if we make the literal unsigned, even though we are negating it. 457 message.add_repeated_int64(-GOOGLE_ULONGLONG(9223372036854775808)); 458 message.add_repeated_uint64(GOOGLE_ULONGLONG(18446744073709551615)); 459 message.add_repeated_double(123.456); 460 message.add_repeated_double(1.23e21); 461 message.add_repeated_double(1.23e-18); 462 message.add_repeated_double(std::numeric_limits<double>::infinity()); 463 message.add_repeated_double(-std::numeric_limits<double>::infinity()); 464 message.add_repeated_double(std::numeric_limits<double>::quiet_NaN()); 465 message.add_repeated_string(string("\000\001\a\b\f\n\r\t\v\\\'\"", 12)); 466 467 // Fun story: We used to use 1.23e22 instead of 1.23e21 above, but this 468 // seemed to trigger an odd case on MinGW/GCC 3.4.5 where GCC's parsing of 469 // the value differed from strtod()'s parsing. That is to say, the 470 // following assertion fails on MinGW: 471 // assert(1.23e22 == strtod("1.23e22", NULL)); 472 // As a result, SimpleDtoa() would print the value as 473 // "1.2300000000000001e+22" to make sure strtod() produce the exact same 474 // result. Our goal is to test runtime parsing, not compile-time parsing, 475 // so this wasn't our problem. It was found that using 1.23e21 did not 476 // have this problem, so we switched to that instead. 477 478 EXPECT_EQ( 479 "repeated_int64: -9223372036854775808\n" 480 "repeated_uint64: 18446744073709551615\n" 481 "repeated_double: 123.456\n" 482 "repeated_double: 1.23e+21\n" 483 "repeated_double: 1.23e-18\n" 484 "repeated_double: inf\n" 485 "repeated_double: -inf\n" 486 "repeated_double: nan\n" 487 "repeated_string: \"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\'\\\"\"\n", 488 RemoveRedundantZeros(message.DebugString())); 489} 490 491TEST_F(TextFormatTest, PrintFloatPrecision) { 492 unittest::TestAllTypes message; 493 494 message.add_repeated_float(1.2); 495 message.add_repeated_float(1.23); 496 message.add_repeated_float(1.234); 497 message.add_repeated_float(1.2345); 498 message.add_repeated_float(1.23456); 499 message.add_repeated_float(1.2e10); 500 message.add_repeated_float(1.23e10); 501 message.add_repeated_float(1.234e10); 502 message.add_repeated_float(1.2345e10); 503 message.add_repeated_float(1.23456e10); 504 message.add_repeated_double(1.2); 505 message.add_repeated_double(1.23); 506 message.add_repeated_double(1.234); 507 message.add_repeated_double(1.2345); 508 message.add_repeated_double(1.23456); 509 message.add_repeated_double(1.234567); 510 message.add_repeated_double(1.2345678); 511 message.add_repeated_double(1.23456789); 512 message.add_repeated_double(1.234567898); 513 message.add_repeated_double(1.2345678987); 514 message.add_repeated_double(1.23456789876); 515 message.add_repeated_double(1.234567898765); 516 message.add_repeated_double(1.2345678987654); 517 message.add_repeated_double(1.23456789876543); 518 message.add_repeated_double(1.2e100); 519 message.add_repeated_double(1.23e100); 520 message.add_repeated_double(1.234e100); 521 message.add_repeated_double(1.2345e100); 522 message.add_repeated_double(1.23456e100); 523 message.add_repeated_double(1.234567e100); 524 message.add_repeated_double(1.2345678e100); 525 message.add_repeated_double(1.23456789e100); 526 message.add_repeated_double(1.234567898e100); 527 message.add_repeated_double(1.2345678987e100); 528 message.add_repeated_double(1.23456789876e100); 529 message.add_repeated_double(1.234567898765e100); 530 message.add_repeated_double(1.2345678987654e100); 531 message.add_repeated_double(1.23456789876543e100); 532 533 EXPECT_EQ( 534 "repeated_float: 1.2\n" 535 "repeated_float: 1.23\n" 536 "repeated_float: 1.234\n" 537 "repeated_float: 1.2345\n" 538 "repeated_float: 1.23456\n" 539 "repeated_float: 1.2e+10\n" 540 "repeated_float: 1.23e+10\n" 541 "repeated_float: 1.234e+10\n" 542 "repeated_float: 1.2345e+10\n" 543 "repeated_float: 1.23456e+10\n" 544 "repeated_double: 1.2\n" 545 "repeated_double: 1.23\n" 546 "repeated_double: 1.234\n" 547 "repeated_double: 1.2345\n" 548 "repeated_double: 1.23456\n" 549 "repeated_double: 1.234567\n" 550 "repeated_double: 1.2345678\n" 551 "repeated_double: 1.23456789\n" 552 "repeated_double: 1.234567898\n" 553 "repeated_double: 1.2345678987\n" 554 "repeated_double: 1.23456789876\n" 555 "repeated_double: 1.234567898765\n" 556 "repeated_double: 1.2345678987654\n" 557 "repeated_double: 1.23456789876543\n" 558 "repeated_double: 1.2e+100\n" 559 "repeated_double: 1.23e+100\n" 560 "repeated_double: 1.234e+100\n" 561 "repeated_double: 1.2345e+100\n" 562 "repeated_double: 1.23456e+100\n" 563 "repeated_double: 1.234567e+100\n" 564 "repeated_double: 1.2345678e+100\n" 565 "repeated_double: 1.23456789e+100\n" 566 "repeated_double: 1.234567898e+100\n" 567 "repeated_double: 1.2345678987e+100\n" 568 "repeated_double: 1.23456789876e+100\n" 569 "repeated_double: 1.234567898765e+100\n" 570 "repeated_double: 1.2345678987654e+100\n" 571 "repeated_double: 1.23456789876543e+100\n", 572 RemoveRedundantZeros(message.DebugString())); 573} 574 575 576TEST_F(TextFormatTest, AllowPartial) { 577 unittest::TestRequired message; 578 TextFormat::Parser parser; 579 parser.AllowPartialMessage(true); 580 EXPECT_TRUE(parser.ParseFromString("a: 1", &message)); 581 EXPECT_EQ(1, message.a()); 582 EXPECT_FALSE(message.has_b()); 583 EXPECT_FALSE(message.has_c()); 584} 585 586TEST_F(TextFormatTest, ParseExotic) { 587 unittest::TestAllTypes message; 588 ASSERT_TRUE(TextFormat::ParseFromString( 589 "repeated_int32: -1\n" 590 "repeated_int32: -2147483648\n" 591 "repeated_int64: -1\n" 592 "repeated_int64: -9223372036854775808\n" 593 "repeated_uint32: 4294967295\n" 594 "repeated_uint32: 2147483648\n" 595 "repeated_uint64: 18446744073709551615\n" 596 "repeated_uint64: 9223372036854775808\n" 597 "repeated_double: 123.0\n" 598 "repeated_double: 123.5\n" 599 "repeated_double: 0.125\n" 600 "repeated_double: 1.23E17\n" 601 "repeated_double: 1.235E+22\n" 602 "repeated_double: 1.235e-18\n" 603 "repeated_double: 123.456789\n" 604 "repeated_double: inf\n" 605 "repeated_double: Infinity\n" 606 "repeated_double: -inf\n" 607 "repeated_double: -Infinity\n" 608 "repeated_double: nan\n" 609 "repeated_double: NaN\n" 610 "repeated_string: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\"\n", 611 &message)); 612 613 ASSERT_EQ(2, message.repeated_int32_size()); 614 EXPECT_EQ(-1, message.repeated_int32(0)); 615 // Note: In C, a negative integer literal is actually the unary negation 616 // operator being applied to a positive integer literal, and 2147483648 is 617 // outside the range of int32. However, it is not outside the range of 618 // uint32. Confusingly, this means that everything works if we make the 619 // literal unsigned, even though we are negating it. 620 EXPECT_EQ(-2147483648u, message.repeated_int32(1)); 621 622 ASSERT_EQ(2, message.repeated_int64_size()); 623 EXPECT_EQ(-1, message.repeated_int64(0)); 624 // Note: In C, a negative integer literal is actually the unary negation 625 // operator being applied to a positive integer literal, and 626 // 9223372036854775808 is outside the range of int64. However, it is not 627 // outside the range of uint64. Confusingly, this means that everything 628 // works if we make the literal unsigned, even though we are negating it. 629 EXPECT_EQ(-GOOGLE_ULONGLONG(9223372036854775808), message.repeated_int64(1)); 630 631 ASSERT_EQ(2, message.repeated_uint32_size()); 632 EXPECT_EQ(4294967295u, message.repeated_uint32(0)); 633 EXPECT_EQ(2147483648u, message.repeated_uint32(1)); 634 635 ASSERT_EQ(2, message.repeated_uint64_size()); 636 EXPECT_EQ(GOOGLE_ULONGLONG(18446744073709551615), message.repeated_uint64(0)); 637 EXPECT_EQ(GOOGLE_ULONGLONG(9223372036854775808), message.repeated_uint64(1)); 638 639 ASSERT_EQ(13, message.repeated_double_size()); 640 EXPECT_EQ(123.0 , message.repeated_double(0)); 641 EXPECT_EQ(123.5 , message.repeated_double(1)); 642 EXPECT_EQ(0.125 , message.repeated_double(2)); 643 EXPECT_EQ(1.23E17 , message.repeated_double(3)); 644 EXPECT_EQ(1.235E22 , message.repeated_double(4)); 645 EXPECT_EQ(1.235E-18 , message.repeated_double(5)); 646 EXPECT_EQ(123.456789, message.repeated_double(6)); 647 EXPECT_EQ(message.repeated_double(7), numeric_limits<double>::infinity()); 648 EXPECT_EQ(message.repeated_double(8), numeric_limits<double>::infinity()); 649 EXPECT_EQ(message.repeated_double(9), -numeric_limits<double>::infinity()); 650 EXPECT_EQ(message.repeated_double(10), -numeric_limits<double>::infinity()); 651 EXPECT_TRUE(IsNaN(message.repeated_double(11))); 652 EXPECT_TRUE(IsNaN(message.repeated_double(12))); 653 654 // Note: Since these string literals have \0's in them, we must explicitly 655 // pass their sizes to string's constructor. 656 ASSERT_EQ(1, message.repeated_string_size()); 657 EXPECT_EQ(string("\000\001\a\b\f\n\r\t\v\\\'\"", 12), 658 message.repeated_string(0)); 659} 660 661class TextFormatParserTest : public testing::Test { 662 protected: 663 void ExpectFailure(const string& input, const string& message, int line, 664 int col) { 665 scoped_ptr<unittest::TestAllTypes> proto(new unittest::TestAllTypes); 666 ExpectFailure(input, message, line, col, proto.get()); 667 } 668 669 void ExpectFailure(const string& input, const string& message, int line, 670 int col, Message* proto) { 671 ExpectMessage(input, message, line, col, proto, false); 672 } 673 674 void ExpectMessage(const string& input, const string& message, int line, 675 int col, Message* proto, bool expected_result) { 676 TextFormat::Parser parser; 677 MockErrorCollector error_collector; 678 parser.RecordErrorsTo(&error_collector); 679 EXPECT_EQ(parser.ParseFromString(input, proto), expected_result); 680 EXPECT_EQ(SimpleItoa(line) + ":" + SimpleItoa(col) + ": " + message + "\n", 681 error_collector.text_); 682 } 683 684 // An error collector which simply concatenates all its errors into a big 685 // block of text which can be checked. 686 class MockErrorCollector : public io::ErrorCollector { 687 public: 688 MockErrorCollector() {} 689 ~MockErrorCollector() {} 690 691 string text_; 692 693 // implements ErrorCollector ------------------------------------- 694 void AddError(int line, int column, const string& message) { 695 strings::SubstituteAndAppend(&text_, "$0:$1: $2\n", 696 line + 1, column + 1, message); 697 } 698 699 void AddWarning(int line, int column, const string& message) { 700 AddError(line, column, "WARNING:" + message); 701 } 702 }; 703}; 704 705TEST_F(TextFormatParserTest, ParseFieldValueFromString) { 706 scoped_ptr<unittest::TestAllTypes> message(new unittest::TestAllTypes); 707 const Descriptor* d = message->GetDescriptor(); 708 709#define EXPECT_FIELD(name, value, valuestring) \ 710 EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \ 711 valuestring, d->FindFieldByName("optional_" #name), message.get())); \ 712 EXPECT_EQ(value, message->optional_##name()); \ 713 EXPECT_TRUE(message->has_optional_##name()); 714 715#define EXPECT_FLOAT_FIELD(name, value, valuestring) \ 716 EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \ 717 valuestring, d->FindFieldByName("optional_" #name), message.get())); \ 718 EXPECT_FLOAT_EQ(value, message->optional_##name()); \ 719 EXPECT_TRUE(message->has_optional_##name()); 720 721#define EXPECT_DOUBLE_FIELD(name, value, valuestring) \ 722 EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \ 723 valuestring, d->FindFieldByName("optional_" #name), message.get())); \ 724 EXPECT_DOUBLE_EQ(value, message->optional_##name()); \ 725 EXPECT_TRUE(message->has_optional_##name()); 726 727#define EXPECT_INVALID(name, valuestring) \ 728 EXPECT_FALSE(TextFormat::ParseFieldValueFromString( \ 729 valuestring, d->FindFieldByName("optional_" #name), message.get())); 730 731 // int32 732 EXPECT_FIELD(int32, 1, "1"); 733 EXPECT_FIELD(int32, -1, "-1"); 734 EXPECT_FIELD(int32, 0x1234, "0x1234"); 735 EXPECT_INVALID(int32, "a"); 736 EXPECT_INVALID(int32, "999999999999999999999999999999999999"); 737 EXPECT_INVALID(int32, "1,2"); 738 739 // int64 740 EXPECT_FIELD(int64, 1, "1"); 741 EXPECT_FIELD(int64, -1, "-1"); 742 EXPECT_FIELD(int64, 0x1234567812345678LL, "0x1234567812345678"); 743 EXPECT_INVALID(int64, "a"); 744 EXPECT_INVALID(int64, "999999999999999999999999999999999999"); 745 EXPECT_INVALID(int64, "1,2"); 746 747 // uint64 748 EXPECT_FIELD(uint64, 1, "1"); 749 EXPECT_FIELD(uint64, 0xf234567812345678ULL, "0xf234567812345678"); 750 EXPECT_INVALID(uint64, "-1"); 751 EXPECT_INVALID(uint64, "a"); 752 EXPECT_INVALID(uint64, "999999999999999999999999999999999999"); 753 EXPECT_INVALID(uint64, "1,2"); 754 755 // fixed32 756 EXPECT_FIELD(fixed32, 1, "1"); 757 EXPECT_FIELD(fixed32, 0x12345678, "0x12345678"); 758 EXPECT_INVALID(fixed32, "-1"); 759 EXPECT_INVALID(fixed32, "a"); 760 EXPECT_INVALID(fixed32, "999999999999999999999999999999999999"); 761 EXPECT_INVALID(fixed32, "1,2"); 762 763 // fixed64 764 EXPECT_FIELD(fixed64, 1, "1"); 765 EXPECT_FIELD(fixed64, 0x1234567812345678ULL, "0x1234567812345678"); 766 EXPECT_INVALID(fixed64, "-1"); 767 EXPECT_INVALID(fixed64, "a"); 768 EXPECT_INVALID(fixed64, "999999999999999999999999999999999999"); 769 EXPECT_INVALID(fixed64, "1,2"); 770 771 // bool 772 EXPECT_FIELD(bool, true, "true"); 773 EXPECT_FIELD(bool, false, "false"); 774 EXPECT_INVALID(bool, "1"); 775 EXPECT_INVALID(bool, "on"); 776 EXPECT_INVALID(bool, "a"); 777 EXPECT_INVALID(bool, "True"); 778 779 // float 780 EXPECT_FIELD(float, 1, "1"); 781 EXPECT_FLOAT_FIELD(float, 1.5, "1.5"); 782 EXPECT_FLOAT_FIELD(float, 1.5e3, "1.5e3"); 783 EXPECT_FLOAT_FIELD(float, -4.55, "-4.55"); 784 EXPECT_INVALID(float, "a"); 785 EXPECT_INVALID(float, "1,2"); 786 787 // double 788 EXPECT_FIELD(double, 1, "1"); 789 EXPECT_FIELD(double, -1, "-1"); 790 EXPECT_DOUBLE_FIELD(double, 2.3, "2.3"); 791 EXPECT_DOUBLE_FIELD(double, 3e5, "3e5"); 792 EXPECT_INVALID(double, "a"); 793 EXPECT_INVALID(double, "1,2"); 794 795 // string 796 EXPECT_FIELD(string, "hello", "\"hello\""); 797 EXPECT_FIELD(string, "-1.87", "'-1.87'"); 798 EXPECT_INVALID(string, "hello"); // without quote for value 799 800 // enum 801 EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAR, "BAR"); 802 EXPECT_INVALID(nested_enum, "1"); // number not supported 803 EXPECT_INVALID(nested_enum, "FOOBAR"); 804 805 // message 806 EXPECT_TRUE(TextFormat::ParseFieldValueFromString( 807 "<bb:12>", d->FindFieldByName("optional_nested_message"), message.get())); 808 EXPECT_EQ(12, message->optional_nested_message().bb()); \ 809 EXPECT_TRUE(message->has_optional_nested_message()); 810 EXPECT_INVALID(nested_message, "any"); 811 812#undef EXPECT_FIELD 813#undef EXPECT_FLOAT_FIELD 814#undef EXPECT_DOUBLE_FIELD 815#undef EXPECT_INVALID 816} 817 818 819TEST_F(TextFormatParserTest, InvalidToken) { 820 ExpectFailure("optional_bool: true\n-5\n", "Expected identifier.", 821 2, 1); 822 823 ExpectFailure("optional_bool: true;\n", "Expected identifier.", 1, 20); 824 ExpectFailure("\"some string\"", "Expected identifier.", 1, 1); 825} 826 827TEST_F(TextFormatParserTest, InvalidFieldName) { 828 ExpectFailure( 829 "invalid_field: somevalue\n", 830 "Message type \"protobuf_unittest.TestAllTypes\" has no field named " 831 "\"invalid_field\".", 832 1, 14); 833} 834 835TEST_F(TextFormatParserTest, InvalidCapitalization) { 836 // We require that group names be exactly as they appear in the .proto. 837 ExpectFailure( 838 "optionalgroup {\na: 15\n}\n", 839 "Message type \"protobuf_unittest.TestAllTypes\" has no field named " 840 "\"optionalgroup\".", 841 1, 15); 842 ExpectFailure( 843 "OPTIONALgroup {\na: 15\n}\n", 844 "Message type \"protobuf_unittest.TestAllTypes\" has no field named " 845 "\"OPTIONALgroup\".", 846 1, 15); 847 ExpectFailure( 848 "Optional_Double: 10.0\n", 849 "Message type \"protobuf_unittest.TestAllTypes\" has no field named " 850 "\"Optional_Double\".", 851 1, 16); 852} 853 854TEST_F(TextFormatParserTest, InvalidFieldValues) { 855 // Invalid values for a double/float field. 856 ExpectFailure("optional_double: \"hello\"\n", "Expected double.", 1, 18); 857 ExpectFailure("optional_double: true\n", "Expected double.", 1, 18); 858 ExpectFailure("optional_double: !\n", "Expected double.", 1, 18); 859 ExpectFailure("optional_double {\n \n}\n", "Expected \":\", found \"{\".", 860 1, 17); 861 862 // Invalid values for a signed integer field. 863 ExpectFailure("optional_int32: \"hello\"\n", "Expected integer.", 1, 17); 864 ExpectFailure("optional_int32: true\n", "Expected integer.", 1, 17); 865 ExpectFailure("optional_int32: 4.5\n", "Expected integer.", 1, 17); 866 ExpectFailure("optional_int32: !\n", "Expected integer.", 1, 17); 867 ExpectFailure("optional_int32 {\n \n}\n", "Expected \":\", found \"{\".", 868 1, 16); 869 ExpectFailure("optional_int32: 0x80000000\n", 870 "Integer out of range.", 1, 17); 871 ExpectFailure("optional_int32: -0x80000001\n", 872 "Integer out of range.", 1, 18); 873 ExpectFailure("optional_int64: 0x8000000000000000\n", 874 "Integer out of range.", 1, 17); 875 ExpectFailure("optional_int64: -0x8000000000000001\n", 876 "Integer out of range.", 1, 18); 877 878 // Invalid values for an unsigned integer field. 879 ExpectFailure("optional_uint64: \"hello\"\n", "Expected integer.", 1, 18); 880 ExpectFailure("optional_uint64: true\n", "Expected integer.", 1, 18); 881 ExpectFailure("optional_uint64: 4.5\n", "Expected integer.", 1, 18); 882 ExpectFailure("optional_uint64: -5\n", "Expected integer.", 1, 18); 883 ExpectFailure("optional_uint64: !\n", "Expected integer.", 1, 18); 884 ExpectFailure("optional_uint64 {\n \n}\n", "Expected \":\", found \"{\".", 885 1, 17); 886 ExpectFailure("optional_uint32: 0x100000000\n", 887 "Integer out of range.", 1, 18); 888 ExpectFailure("optional_uint64: 0x10000000000000000\n", 889 "Integer out of range.", 1, 18); 890 891 // Invalid values for a boolean field. 892 ExpectFailure("optional_bool: \"hello\"\n", "Expected identifier.", 1, 16); 893 ExpectFailure("optional_bool: 5\n", "Expected identifier.", 1, 16); 894 ExpectFailure("optional_bool: -7.5\n", "Expected identifier.", 1, 16); 895 ExpectFailure("optional_bool: !\n", "Expected identifier.", 1, 16); 896 897 ExpectFailure( 898 "optional_bool: meh\n", 899 "Invalid value for boolean field \"optional_bool\". Value: \"meh\".", 900 2, 1); 901 902 ExpectFailure("optional_bool {\n \n}\n", "Expected \":\", found \"{\".", 903 1, 15); 904 905 // Invalid values for a string field. 906 ExpectFailure("optional_string: true\n", "Expected string.", 1, 18); 907 ExpectFailure("optional_string: 5\n", "Expected string.", 1, 18); 908 ExpectFailure("optional_string: -7.5\n", "Expected string.", 1, 18); 909 ExpectFailure("optional_string: !\n", "Expected string.", 1, 18); 910 ExpectFailure("optional_string {\n \n}\n", "Expected \":\", found \"{\".", 911 1, 17); 912 913 // Invalid values for an enumeration field. 914 ExpectFailure("optional_nested_enum: \"hello\"\n", "Expected identifier.", 915 1, 23); 916 917 ExpectFailure("optional_nested_enum: 5\n", "Expected identifier.", 1, 23); 918 ExpectFailure("optional_nested_enum: -7.5\n", "Expected identifier.", 1, 23); 919 ExpectFailure("optional_nested_enum: !\n", "Expected identifier.", 1, 23); 920 921 ExpectFailure( 922 "optional_nested_enum: grah\n", 923 "Unknown enumeration value of \"grah\" for field " 924 "\"optional_nested_enum\".", 2, 1); 925 926 ExpectFailure( 927 "optional_nested_enum {\n \n}\n", 928 "Expected \":\", found \"{\".", 1, 22); 929} 930 931TEST_F(TextFormatParserTest, MessageDelimeters) { 932 // Non-matching delimeters. 933 ExpectFailure("OptionalGroup <\n \n}\n", "Expected \">\", found \"}\".", 934 3, 1); 935 936 // Invalid delimeters. 937 ExpectFailure("OptionalGroup [\n \n]\n", "Expected \"{\", found \"[\".", 938 1, 15); 939 940 // Unending message. 941 ExpectFailure("optional_nested_message {\n \nbb: 118\n", 942 "Expected identifier.", 943 4, 1); 944} 945 946TEST_F(TextFormatParserTest, UnknownExtension) { 947 // Non-matching delimeters. 948 ExpectFailure("[blahblah]: 123", 949 "Extension \"blahblah\" is not defined or is not an " 950 "extension of \"protobuf_unittest.TestAllTypes\".", 951 1, 11); 952} 953 954TEST_F(TextFormatParserTest, MissingRequired) { 955 unittest::TestRequired message; 956 ExpectFailure("a: 1", 957 "Message missing required fields: b, c", 958 0, 1, &message); 959} 960 961TEST_F(TextFormatParserTest, ParseDuplicateRequired) { 962 unittest::TestRequired message; 963 ExpectFailure("a: 1 b: 2 c: 3 a: 1", 964 "Non-repeated field \"a\" is specified multiple times.", 965 1, 17, &message); 966} 967 968TEST_F(TextFormatParserTest, ParseDuplicateOptional) { 969 unittest::ForeignMessage message; 970 ExpectFailure("c: 1 c: 2", 971 "Non-repeated field \"c\" is specified multiple times.", 972 1, 7, &message); 973} 974 975TEST_F(TextFormatParserTest, MergeDuplicateRequired) { 976 unittest::TestRequired message; 977 TextFormat::Parser parser; 978 EXPECT_TRUE(parser.MergeFromString("a: 1 b: 2 c: 3 a: 4", &message)); 979 EXPECT_EQ(4, message.a()); 980} 981 982TEST_F(TextFormatParserTest, MergeDuplicateOptional) { 983 unittest::ForeignMessage message; 984 TextFormat::Parser parser; 985 EXPECT_TRUE(parser.MergeFromString("c: 1 c: 2", &message)); 986 EXPECT_EQ(2, message.c()); 987} 988 989TEST_F(TextFormatParserTest, PrintErrorsToStderr) { 990 vector<string> errors; 991 992 { 993 ScopedMemoryLog log; 994 unittest::TestAllTypes proto; 995 EXPECT_FALSE(TextFormat::ParseFromString("no_such_field: 1", &proto)); 996 errors = log.GetMessages(ERROR); 997 } 998 999 ASSERT_EQ(1, errors.size()); 1000 EXPECT_EQ("Error parsing text-format protobuf_unittest.TestAllTypes: " 1001 "1:14: Message type \"protobuf_unittest.TestAllTypes\" has no field " 1002 "named \"no_such_field\".", 1003 errors[0]); 1004} 1005 1006TEST_F(TextFormatParserTest, FailsOnTokenizationError) { 1007 vector<string> errors; 1008 1009 { 1010 ScopedMemoryLog log; 1011 unittest::TestAllTypes proto; 1012 EXPECT_FALSE(TextFormat::ParseFromString("\020", &proto)); 1013 errors = log.GetMessages(ERROR); 1014 } 1015 1016 ASSERT_EQ(1, errors.size()); 1017 EXPECT_EQ("Error parsing text-format protobuf_unittest.TestAllTypes: " 1018 "1:1: Invalid control characters encountered in text.", 1019 errors[0]); 1020} 1021 1022TEST_F(TextFormatParserTest, ParseDeprecatedField) { 1023 unittest::TestDeprecatedFields message; 1024 ExpectMessage("deprecated_int32: 42", 1025 "WARNING:text format contains deprecated field " 1026 "\"deprecated_int32\"", 1, 21, &message, true); 1027} 1028 1029class TextFormatMessageSetTest : public testing::Test { 1030 protected: 1031 static const char proto_debug_string_[]; 1032}; 1033const char TextFormatMessageSetTest::proto_debug_string_[] = 1034"message_set {\n" 1035" [protobuf_unittest.TestMessageSetExtension1] {\n" 1036" i: 23\n" 1037" }\n" 1038" [protobuf_unittest.TestMessageSetExtension2] {\n" 1039" str: \"foo\"\n" 1040" }\n" 1041"}\n"; 1042 1043 1044TEST_F(TextFormatMessageSetTest, Serialize) { 1045 protobuf_unittest::TestMessageSetContainer proto; 1046 protobuf_unittest::TestMessageSetExtension1* item_a = 1047 proto.mutable_message_set()->MutableExtension( 1048 protobuf_unittest::TestMessageSetExtension1::message_set_extension); 1049 item_a->set_i(23); 1050 protobuf_unittest::TestMessageSetExtension2* item_b = 1051 proto.mutable_message_set()->MutableExtension( 1052 protobuf_unittest::TestMessageSetExtension2::message_set_extension); 1053 item_b->set_str("foo"); 1054 EXPECT_EQ(proto_debug_string_, proto.DebugString()); 1055} 1056 1057TEST_F(TextFormatMessageSetTest, Deserialize) { 1058 protobuf_unittest::TestMessageSetContainer proto; 1059 ASSERT_TRUE(TextFormat::ParseFromString(proto_debug_string_, &proto)); 1060 EXPECT_EQ(23, proto.message_set().GetExtension( 1061 protobuf_unittest::TestMessageSetExtension1::message_set_extension).i()); 1062 EXPECT_EQ("foo", proto.message_set().GetExtension( 1063 protobuf_unittest::TestMessageSetExtension2::message_set_extension).str()); 1064 1065 // Ensure that these are the only entries present. 1066 vector<const FieldDescriptor*> descriptors; 1067 proto.message_set().GetReflection()->ListFields( 1068 proto.message_set(), &descriptors); 1069 EXPECT_EQ(2, descriptors.size()); 1070} 1071 1072} // namespace text_format_unittest 1073} // namespace protobuf 1074} // namespace google 1075