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