1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
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
53 namespace google {
54 namespace protobuf {
55
56 // Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
57 namespace text_format_unittest {
58
IsNaN(double value)59 inline 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.
65 const 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.
70 const string kEscapeTestStringEscaped =
71 "\"\\\"A string with \\' characters \\n and \\r newlines "
72 "and \\t tabs and \\001 slashes \\\\ and multiple spaces\"";
73
74 class TextFormatTest : public testing::Test {
75 public:
SetUpTestCase()76 static void SetUpTestCase() {
77 GOOGLE_CHECK_OK(File::GetContents(
78 TestSourceDir() +
79 "/google/protobuf/"
80 "testdata/text_format_unittest_data_oneof_implemented.txt",
81 &static_proto_debug_string_, true));
82 }
83
TextFormatTest()84 TextFormatTest() : proto_debug_string_(static_proto_debug_string_) {}
85
86 protected:
87 // Debug string read from text_format_unittest_data.txt.
88 const string proto_debug_string_;
89 unittest::TestAllTypes proto_;
90
91 private:
92 static string static_proto_debug_string_;
93 };
94 string TextFormatTest::static_proto_debug_string_;
95
96 class TextFormatExtensionsTest : public testing::Test {
97 public:
SetUpTestCase()98 static void SetUpTestCase() {
99 GOOGLE_CHECK_OK(File::GetContents(TestSourceDir() +
100 "/google/protobuf/testdata/"
101 "text_format_unittest_extensions_data.txt",
102 &static_proto_debug_string_, true));
103 }
104
TextFormatExtensionsTest()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 };
116 string TextFormatExtensionsTest::static_proto_debug_string_;
117
118
TEST_F(TextFormatTest,Basic)119 TEST_F(TextFormatTest, Basic) {
120 TestUtil::SetAllFields(&proto_);
121 EXPECT_EQ(proto_debug_string_, proto_.DebugString());
122 }
123
TEST_F(TextFormatExtensionsTest,Extensions)124 TEST_F(TextFormatExtensionsTest, Extensions) {
125 TestUtil::SetAllExtensions(&proto_);
126 EXPECT_EQ(proto_debug_string_, proto_.DebugString());
127 }
128
TEST_F(TextFormatTest,ShortDebugString)129 TEST_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
TEST_F(TextFormatTest,ShortPrimitiveRepeateds)141 TEST_F(TextFormatTest, ShortPrimitiveRepeateds) {
142 proto_.set_optional_int32(123);
143 proto_.add_repeated_int32(456);
144 proto_.add_repeated_int32(789);
145 proto_.add_repeated_string("foo");
146 proto_.add_repeated_string("bar");
147 proto_.add_repeated_nested_message()->set_bb(2);
148 proto_.add_repeated_nested_message()->set_bb(3);
149 proto_.add_repeated_nested_enum(unittest::TestAllTypes::FOO);
150 proto_.add_repeated_nested_enum(unittest::TestAllTypes::BAR);
151
152 TextFormat::Printer printer;
153 printer.SetUseShortRepeatedPrimitives(true);
154 string text;
155 printer.PrintToString(proto_, &text);
156
157 EXPECT_EQ("optional_int32: 123\n"
158 "repeated_int32: [456, 789]\n"
159 "repeated_string: \"foo\"\n"
160 "repeated_string: \"bar\"\n"
161 "repeated_nested_message {\n bb: 2\n}\n"
162 "repeated_nested_message {\n bb: 3\n}\n"
163 "repeated_nested_enum: [FOO, BAR]\n",
164 text);
165
166 // Try in single-line mode.
167 printer.SetSingleLineMode(true);
168 printer.PrintToString(proto_, &text);
169
170 EXPECT_EQ("optional_int32: 123 "
171 "repeated_int32: [456, 789] "
172 "repeated_string: \"foo\" "
173 "repeated_string: \"bar\" "
174 "repeated_nested_message { bb: 2 } "
175 "repeated_nested_message { bb: 3 } "
176 "repeated_nested_enum: [FOO, BAR] ",
177 text);
178 }
179
180
TEST_F(TextFormatTest,StringEscape)181 TEST_F(TextFormatTest, StringEscape) {
182 // Set the string value to test.
183 proto_.set_optional_string(kEscapeTestString);
184
185 // Get the DebugString from the proto.
186 string debug_string = proto_.DebugString();
187 string utf8_debug_string = proto_.Utf8DebugString();
188
189 // Hardcode a correct value to test against.
190 string correct_string = "optional_string: "
191 + kEscapeTestStringEscaped
192 + "\n";
193
194 // Compare.
195 EXPECT_EQ(correct_string, debug_string);
196 // UTF-8 string is the same as non-UTF-8 because
197 // the protocol buffer contains no UTF-8 text.
198 EXPECT_EQ(correct_string, utf8_debug_string);
199
200 string expected_short_debug_string = "optional_string: "
201 + kEscapeTestStringEscaped;
202 EXPECT_EQ(expected_short_debug_string, proto_.ShortDebugString());
203 }
204
TEST_F(TextFormatTest,Utf8DebugString)205 TEST_F(TextFormatTest, Utf8DebugString) {
206 // Set the string value to test.
207 proto_.set_optional_string("\350\260\267\346\255\214");
208 proto_.set_optional_bytes("\350\260\267\346\255\214");
209
210 // Get the DebugString from the proto.
211 string debug_string = proto_.DebugString();
212 string utf8_debug_string = proto_.Utf8DebugString();
213
214 // Hardcode a correct value to test against.
215 string correct_utf8_string =
216 "optional_string: "
217 "\"\350\260\267\346\255\214\""
218 "\n"
219 "optional_bytes: "
220 "\"\\350\\260\\267\\346\\255\\214\""
221 "\n";
222 string correct_string =
223 "optional_string: "
224 "\"\\350\\260\\267\\346\\255\\214\""
225 "\n"
226 "optional_bytes: "
227 "\"\\350\\260\\267\\346\\255\\214\""
228 "\n";
229
230 // Compare.
231 EXPECT_EQ(correct_utf8_string, utf8_debug_string);
232 EXPECT_EQ(correct_string, debug_string);
233 }
234
TEST_F(TextFormatTest,PrintUnknownFields)235 TEST_F(TextFormatTest, PrintUnknownFields) {
236 // Test printing of unknown fields in a message.
237
238 unittest::TestEmptyMessage message;
239 UnknownFieldSet* unknown_fields = message.mutable_unknown_fields();
240
241 unknown_fields->AddVarint(5, 1);
242 unknown_fields->AddFixed32(5, 2);
243 unknown_fields->AddFixed64(5, 3);
244 unknown_fields->AddLengthDelimited(5, "4");
245 unknown_fields->AddGroup(5)->AddVarint(10, 5);
246
247 unknown_fields->AddVarint(8, 1);
248 unknown_fields->AddVarint(8, 2);
249 unknown_fields->AddVarint(8, 3);
250
251 EXPECT_EQ(
252 "5: 1\n"
253 "5: 0x00000002\n"
254 "5: 0x0000000000000003\n"
255 "5: \"4\"\n"
256 "5 {\n"
257 " 10: 5\n"
258 "}\n"
259 "8: 1\n"
260 "8: 2\n"
261 "8: 3\n",
262 message.DebugString());
263 }
264
TEST_F(TextFormatTest,PrintUnknownFieldsHidden)265 TEST_F(TextFormatTest, PrintUnknownFieldsHidden) {
266 // Test printing of unknown fields in a message when supressed.
267
268 unittest::OneString message;
269 message.set_data("data");
270 UnknownFieldSet* unknown_fields = message.mutable_unknown_fields();
271
272 unknown_fields->AddVarint(5, 1);
273 unknown_fields->AddFixed32(5, 2);
274 unknown_fields->AddFixed64(5, 3);
275 unknown_fields->AddLengthDelimited(5, "4");
276 unknown_fields->AddGroup(5)->AddVarint(10, 5);
277
278 unknown_fields->AddVarint(8, 1);
279 unknown_fields->AddVarint(8, 2);
280 unknown_fields->AddVarint(8, 3);
281
282 TextFormat::Printer printer;
283 printer.SetHideUnknownFields(true);
284 string output;
285 printer.PrintToString(message, &output);
286
287 EXPECT_EQ("data: \"data\"\n", output);
288 }
289
TEST_F(TextFormatTest,PrintUnknownMessage)290 TEST_F(TextFormatTest, PrintUnknownMessage) {
291 // Test heuristic printing of messages in an UnknownFieldSet.
292
293 protobuf_unittest::TestAllTypes message;
294
295 // Cases which should not be interpreted as sub-messages.
296
297 // 'a' is a valid FIXED64 tag, so for the string to be parseable as a message
298 // it should be followed by 8 bytes. Since this string only has two
299 // subsequent bytes, it should be treated as a string.
300 message.add_repeated_string("abc");
301
302 // 'd' happens to be a valid ENDGROUP tag. So,
303 // UnknownFieldSet::MergeFromCodedStream() will successfully parse "def", but
304 // the ConsumedEntireMessage() check should fail.
305 message.add_repeated_string("def");
306
307 // A zero-length string should never be interpreted as a message even though
308 // it is technically valid as one.
309 message.add_repeated_string("");
310
311 // Case which should be interpreted as a sub-message.
312
313 // An actual nested message with content should always be interpreted as a
314 // nested message.
315 message.add_repeated_nested_message()->set_bb(123);
316
317 string data;
318 message.SerializeToString(&data);
319
320 string text;
321 UnknownFieldSet unknown_fields;
322 EXPECT_TRUE(unknown_fields.ParseFromString(data));
323 EXPECT_TRUE(TextFormat::PrintUnknownFieldsToString(unknown_fields, &text));
324 EXPECT_EQ(
325 "44: \"abc\"\n"
326 "44: \"def\"\n"
327 "44: \"\"\n"
328 "48 {\n"
329 " 1: 123\n"
330 "}\n",
331 text);
332 }
333
TEST_F(TextFormatTest,PrintMessageWithIndent)334 TEST_F(TextFormatTest, PrintMessageWithIndent) {
335 // Test adding an initial indent to printing.
336
337 protobuf_unittest::TestAllTypes message;
338
339 message.add_repeated_string("abc");
340 message.add_repeated_string("def");
341 message.add_repeated_nested_message()->set_bb(123);
342
343 string text;
344 TextFormat::Printer printer;
345 printer.SetInitialIndentLevel(1);
346 EXPECT_TRUE(printer.PrintToString(message, &text));
347 EXPECT_EQ(
348 " repeated_string: \"abc\"\n"
349 " repeated_string: \"def\"\n"
350 " repeated_nested_message {\n"
351 " bb: 123\n"
352 " }\n",
353 text);
354 }
355
TEST_F(TextFormatTest,PrintMessageSingleLine)356 TEST_F(TextFormatTest, PrintMessageSingleLine) {
357 // Test printing a message on a single line.
358
359 protobuf_unittest::TestAllTypes message;
360
361 message.add_repeated_string("abc");
362 message.add_repeated_string("def");
363 message.add_repeated_nested_message()->set_bb(123);
364
365 string text;
366 TextFormat::Printer printer;
367 printer.SetInitialIndentLevel(1);
368 printer.SetSingleLineMode(true);
369 EXPECT_TRUE(printer.PrintToString(message, &text));
370 EXPECT_EQ(
371 " repeated_string: \"abc\" repeated_string: \"def\" "
372 "repeated_nested_message { bb: 123 } ",
373 text);
374 }
375
TEST_F(TextFormatTest,PrintBufferTooSmall)376 TEST_F(TextFormatTest, PrintBufferTooSmall) {
377 // Test printing a message to a buffer that is too small.
378
379 protobuf_unittest::TestAllTypes message;
380
381 message.add_repeated_string("abc");
382 message.add_repeated_string("def");
383
384 char buffer[1] = "";
385 io::ArrayOutputStream output_stream(buffer, 1);
386 EXPECT_FALSE(TextFormat::Print(message, &output_stream));
387 EXPECT_EQ(buffer[0], 'r');
388 EXPECT_EQ(output_stream.ByteCount(), 1);
389 }
390
391 // A printer that appends 'u' to all unsigned int32.
392 class CustomUInt32FieldValuePrinter : public TextFormat::FieldValuePrinter {
393 public:
PrintUInt32(uint32 val) const394 virtual string PrintUInt32(uint32 val) const {
395 return StrCat(FieldValuePrinter::PrintUInt32(val), "u");
396 }
397 };
398
TEST_F(TextFormatTest,DefaultCustomFieldPrinter)399 TEST_F(TextFormatTest, DefaultCustomFieldPrinter) {
400 protobuf_unittest::TestAllTypes message;
401
402 message.set_optional_uint32(42);
403 message.add_repeated_uint32(1);
404 message.add_repeated_uint32(2);
405 message.add_repeated_uint32(3);
406
407 TextFormat::Printer printer;
408 printer.SetDefaultFieldValuePrinter(new CustomUInt32FieldValuePrinter());
409 // Let's see if that works well together with the repeated primitives:
410 printer.SetUseShortRepeatedPrimitives(true);
411 string text;
412 printer.PrintToString(message, &text);
413 EXPECT_EQ("optional_uint32: 42u\nrepeated_uint32: [1u, 2u, 3u]\n", text);
414 }
415
416 class CustomInt32FieldValuePrinter : public TextFormat::FieldValuePrinter {
417 public:
PrintInt32(int32 val) const418 virtual string PrintInt32(int32 val) const {
419 return StrCat("value-is(", FieldValuePrinter::PrintInt32(val), ")");
420 }
421 };
422
TEST_F(TextFormatTest,FieldSpecificCustomPrinter)423 TEST_F(TextFormatTest, FieldSpecificCustomPrinter) {
424 protobuf_unittest::TestAllTypes message;
425
426 message.set_optional_int32(42); // This will be handled by our Printer.
427 message.add_repeated_int32(42); // This will be printed as number.
428
429 TextFormat::Printer printer;
430 EXPECT_TRUE(printer.RegisterFieldValuePrinter(
431 message.GetDescriptor()->FindFieldByName("optional_int32"),
432 new CustomInt32FieldValuePrinter()));
433 string text;
434 printer.PrintToString(message, &text);
435 EXPECT_EQ("optional_int32: value-is(42)\nrepeated_int32: 42\n", text);
436 }
437
TEST_F(TextFormatTest,ErrorCasesRegisteringFieldValuePrinterShouldFail)438 TEST_F(TextFormatTest, ErrorCasesRegisteringFieldValuePrinterShouldFail) {
439 protobuf_unittest::TestAllTypes message;
440 TextFormat::Printer printer;
441 // NULL printer.
442 EXPECT_FALSE(printer.RegisterFieldValuePrinter(
443 message.GetDescriptor()->FindFieldByName("optional_int32"),
444 NULL));
445 // Because registration fails, the ownership of this printer is never taken.
446 TextFormat::FieldValuePrinter my_field_printer;
447 // NULL field
448 EXPECT_FALSE(printer.RegisterFieldValuePrinter(NULL, &my_field_printer));
449 }
450
451 class CustomMessageFieldValuePrinter : public TextFormat::FieldValuePrinter {
452 public:
PrintInt32(int32 v) const453 virtual string PrintInt32(int32 v) const {
454 return StrCat(FieldValuePrinter::PrintInt32(v), " # x", ToHex(v));
455 }
456
PrintMessageStart(const Message & message,int field_index,int field_count,bool single_line_mode) const457 virtual string PrintMessageStart(const Message& message,
458 int field_index,
459 int field_count,
460 bool single_line_mode) const {
461 if (single_line_mode) {
462 return " { ";
463 }
464 return StrCat(
465 " { # ", message.GetDescriptor()->name(), ": ", field_index, "\n");
466 }
467 };
468
TEST_F(TextFormatTest,CustomPrinterForComments)469 TEST_F(TextFormatTest, CustomPrinterForComments) {
470 protobuf_unittest::TestAllTypes message;
471 message.mutable_optional_nested_message();
472 message.mutable_optional_import_message()->set_d(42);
473 message.add_repeated_nested_message();
474 message.add_repeated_nested_message();
475 message.add_repeated_import_message()->set_d(43);
476 message.add_repeated_import_message()->set_d(44);
477 TextFormat::Printer printer;
478 CustomMessageFieldValuePrinter my_field_printer;
479 printer.SetDefaultFieldValuePrinter(new CustomMessageFieldValuePrinter());
480 string text;
481 printer.PrintToString(message, &text);
482 EXPECT_EQ(
483 "optional_nested_message { # NestedMessage: -1\n"
484 "}\n"
485 "optional_import_message { # ImportMessage: -1\n"
486 " d: 42 # x2a\n"
487 "}\n"
488 "repeated_nested_message { # NestedMessage: 0\n"
489 "}\n"
490 "repeated_nested_message { # NestedMessage: 1\n"
491 "}\n"
492 "repeated_import_message { # ImportMessage: 0\n"
493 " d: 43 # x2b\n"
494 "}\n"
495 "repeated_import_message { # ImportMessage: 1\n"
496 " d: 44 # x2c\n"
497 "}\n",
498 text);
499 }
500
501 class CustomMultilineCommentPrinter : public TextFormat::FieldValuePrinter {
502 public:
PrintMessageStart(const Message & message,int field_index,int field_count,bool single_line_comment) const503 virtual string PrintMessageStart(const Message& message,
504 int field_index,
505 int field_count,
506 bool single_line_comment) const {
507 return StrCat(" { # 1\n", " # 2\n");
508 }
509 };
510
TEST_F(TextFormatTest,CustomPrinterForMultilineComments)511 TEST_F(TextFormatTest, CustomPrinterForMultilineComments) {
512 protobuf_unittest::TestAllTypes message;
513 message.mutable_optional_nested_message();
514 message.mutable_optional_import_message()->set_d(42);
515 TextFormat::Printer printer;
516 CustomMessageFieldValuePrinter my_field_printer;
517 printer.SetDefaultFieldValuePrinter(new CustomMultilineCommentPrinter());
518 string text;
519 printer.PrintToString(message, &text);
520 EXPECT_EQ(
521 "optional_nested_message { # 1\n"
522 " # 2\n"
523 "}\n"
524 "optional_import_message { # 1\n"
525 " # 2\n"
526 " d: 42\n"
527 "}\n",
528 text);
529 }
530
TEST_F(TextFormatTest,ParseBasic)531 TEST_F(TextFormatTest, ParseBasic) {
532 io::ArrayInputStream input_stream(proto_debug_string_.data(),
533 proto_debug_string_.size());
534 TextFormat::Parse(&input_stream, &proto_);
535 TestUtil::ExpectAllFieldsSet(proto_);
536 }
537
TEST_F(TextFormatExtensionsTest,ParseExtensions)538 TEST_F(TextFormatExtensionsTest, ParseExtensions) {
539 io::ArrayInputStream input_stream(proto_debug_string_.data(),
540 proto_debug_string_.size());
541 TextFormat::Parse(&input_stream, &proto_);
542 TestUtil::ExpectAllExtensionsSet(proto_);
543 }
544
TEST_F(TextFormatTest,ParseEnumFieldFromNumber)545 TEST_F(TextFormatTest, ParseEnumFieldFromNumber) {
546 // Create a parse string with a numerical value for an enum field.
547 string parse_string = strings::Substitute("optional_nested_enum: $0",
548 unittest::TestAllTypes::BAZ);
549 EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto_));
550 EXPECT_TRUE(proto_.has_optional_nested_enum());
551 EXPECT_EQ(unittest::TestAllTypes::BAZ, proto_.optional_nested_enum());
552 }
553
TEST_F(TextFormatTest,ParseEnumFieldFromNegativeNumber)554 TEST_F(TextFormatTest, ParseEnumFieldFromNegativeNumber) {
555 ASSERT_LT(unittest::SPARSE_E, 0);
556 string parse_string = strings::Substitute("sparse_enum: $0",
557 unittest::SPARSE_E);
558 unittest::SparseEnumMessage proto;
559 EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto));
560 EXPECT_TRUE(proto.has_sparse_enum());
561 EXPECT_EQ(unittest::SPARSE_E, proto.sparse_enum());
562 }
563
TEST_F(TextFormatTest,ParseStringEscape)564 TEST_F(TextFormatTest, ParseStringEscape) {
565 // Create a parse string with escpaed characters in it.
566 string parse_string = "optional_string: "
567 + kEscapeTestStringEscaped
568 + "\n";
569
570 io::ArrayInputStream input_stream(parse_string.data(),
571 parse_string.size());
572 TextFormat::Parse(&input_stream, &proto_);
573
574 // Compare.
575 EXPECT_EQ(kEscapeTestString, proto_.optional_string());
576 }
577
TEST_F(TextFormatTest,ParseConcatenatedString)578 TEST_F(TextFormatTest, ParseConcatenatedString) {
579 // Create a parse string with multiple parts on one line.
580 string parse_string = "optional_string: \"foo\" \"bar\"\n";
581
582 io::ArrayInputStream input_stream1(parse_string.data(),
583 parse_string.size());
584 TextFormat::Parse(&input_stream1, &proto_);
585
586 // Compare.
587 EXPECT_EQ("foobar", proto_.optional_string());
588
589 // Create a parse string with multiple parts on seperate lines.
590 parse_string = "optional_string: \"foo\"\n"
591 "\"bar\"\n";
592
593 io::ArrayInputStream input_stream2(parse_string.data(),
594 parse_string.size());
595 TextFormat::Parse(&input_stream2, &proto_);
596
597 // Compare.
598 EXPECT_EQ("foobar", proto_.optional_string());
599 }
600
TEST_F(TextFormatTest,ParseFloatWithSuffix)601 TEST_F(TextFormatTest, ParseFloatWithSuffix) {
602 // Test that we can parse a floating-point value with 'f' appended to the
603 // end. This is needed for backwards-compatibility with proto1.
604
605 // Have it parse a float with the 'f' suffix.
606 string parse_string = "optional_float: 1.0f\n";
607
608 io::ArrayInputStream input_stream(parse_string.data(),
609 parse_string.size());
610
611 TextFormat::Parse(&input_stream, &proto_);
612
613 // Compare.
614 EXPECT_EQ(1.0, proto_.optional_float());
615 }
616
TEST_F(TextFormatTest,ParseShortRepeatedForm)617 TEST_F(TextFormatTest, ParseShortRepeatedForm) {
618 string parse_string =
619 // Mixed short-form and long-form are simply concatenated.
620 "repeated_int32: 1\n"
621 "repeated_int32: [456, 789]\n"
622 "repeated_nested_enum: [ FOO ,BAR, # comment\n"
623 " 3]\n"
624 // Note that while the printer won't print repeated strings in short-form,
625 // the parser will accept them.
626 "repeated_string: [ \"foo\", 'bar' ]\n"
627 // Repeated message
628 "repeated_nested_message: [ { bb: 1 }, { bb : 2 }]\n"
629 // Repeated group
630 "RepeatedGroup [{ a: 3 },{ a: 4 }]\n";
631
632 ASSERT_TRUE(TextFormat::ParseFromString(parse_string, &proto_));
633
634 ASSERT_EQ(3, proto_.repeated_int32_size());
635 EXPECT_EQ(1, proto_.repeated_int32(0));
636 EXPECT_EQ(456, proto_.repeated_int32(1));
637 EXPECT_EQ(789, proto_.repeated_int32(2));
638
639 ASSERT_EQ(3, proto_.repeated_nested_enum_size());
640 EXPECT_EQ(unittest::TestAllTypes::FOO, proto_.repeated_nested_enum(0));
641 EXPECT_EQ(unittest::TestAllTypes::BAR, proto_.repeated_nested_enum(1));
642 EXPECT_EQ(unittest::TestAllTypes::BAZ, proto_.repeated_nested_enum(2));
643
644 ASSERT_EQ(2, proto_.repeated_string_size());
645 EXPECT_EQ("foo", proto_.repeated_string(0));
646 EXPECT_EQ("bar", proto_.repeated_string(1));
647
648 ASSERT_EQ(2, proto_.repeated_nested_message_size());
649 EXPECT_EQ(1, proto_.repeated_nested_message(0).bb());
650 EXPECT_EQ(2, proto_.repeated_nested_message(1).bb());
651
652 ASSERT_EQ(2, proto_.repeatedgroup_size());
653 EXPECT_EQ(3, proto_.repeatedgroup(0).a());
654 EXPECT_EQ(4, proto_.repeatedgroup(1).a());
655 }
656
657
TEST_F(TextFormatTest,Comments)658 TEST_F(TextFormatTest, Comments) {
659 // Test that comments are ignored.
660
661 string parse_string = "optional_int32: 1 # a comment\n"
662 "optional_int64: 2 # another comment";
663
664 io::ArrayInputStream input_stream(parse_string.data(),
665 parse_string.size());
666
667 TextFormat::Parse(&input_stream, &proto_);
668
669 // Compare.
670 EXPECT_EQ(1, proto_.optional_int32());
671 EXPECT_EQ(2, proto_.optional_int64());
672 }
673
TEST_F(TextFormatTest,OptionalColon)674 TEST_F(TextFormatTest, OptionalColon) {
675 // Test that we can place a ':' after the field name of a nested message,
676 // even though we don't have to.
677
678 string parse_string = "optional_nested_message: { bb: 1}\n";
679
680 io::ArrayInputStream input_stream(parse_string.data(),
681 parse_string.size());
682
683 TextFormat::Parse(&input_stream, &proto_);
684
685 // Compare.
686 EXPECT_TRUE(proto_.has_optional_nested_message());
687 EXPECT_EQ(1, proto_.optional_nested_message().bb());
688 }
689
690 // Some platforms (e.g. Windows) insist on padding the exponent to three
691 // digits when one or two would be just fine.
RemoveRedundantZeros(string text)692 static string RemoveRedundantZeros(string text) {
693 text = StringReplace(text, "e+0", "e+", true);
694 text = StringReplace(text, "e-0", "e-", true);
695 return text;
696 }
697
TEST_F(TextFormatTest,PrintExotic)698 TEST_F(TextFormatTest, PrintExotic) {
699 unittest::TestAllTypes message;
700
701 // Note: In C, a negative integer literal is actually the unary negation
702 // operator being applied to a positive integer literal, and
703 // 9223372036854775808 is outside the range of int64. However, it is not
704 // outside the range of uint64. Confusingly, this means that everything
705 // works if we make the literal unsigned, even though we are negating it.
706 message.add_repeated_int64(-GOOGLE_ULONGLONG(9223372036854775808));
707 message.add_repeated_uint64(GOOGLE_ULONGLONG(18446744073709551615));
708 message.add_repeated_double(123.456);
709 message.add_repeated_double(1.23e21);
710 message.add_repeated_double(1.23e-18);
711 message.add_repeated_double(std::numeric_limits<double>::infinity());
712 message.add_repeated_double(-std::numeric_limits<double>::infinity());
713 message.add_repeated_double(std::numeric_limits<double>::quiet_NaN());
714 message.add_repeated_string(string("\000\001\a\b\f\n\r\t\v\\\'\"", 12));
715
716 // Fun story: We used to use 1.23e22 instead of 1.23e21 above, but this
717 // seemed to trigger an odd case on MinGW/GCC 3.4.5 where GCC's parsing of
718 // the value differed from strtod()'s parsing. That is to say, the
719 // following assertion fails on MinGW:
720 // assert(1.23e22 == strtod("1.23e22", NULL));
721 // As a result, SimpleDtoa() would print the value as
722 // "1.2300000000000001e+22" to make sure strtod() produce the exact same
723 // result. Our goal is to test runtime parsing, not compile-time parsing,
724 // so this wasn't our problem. It was found that using 1.23e21 did not
725 // have this problem, so we switched to that instead.
726
727 EXPECT_EQ(
728 "repeated_int64: -9223372036854775808\n"
729 "repeated_uint64: 18446744073709551615\n"
730 "repeated_double: 123.456\n"
731 "repeated_double: 1.23e+21\n"
732 "repeated_double: 1.23e-18\n"
733 "repeated_double: inf\n"
734 "repeated_double: -inf\n"
735 "repeated_double: nan\n"
736 "repeated_string: \"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\'\\\"\"\n",
737 RemoveRedundantZeros(message.DebugString()));
738 }
739
TEST_F(TextFormatTest,PrintFloatPrecision)740 TEST_F(TextFormatTest, PrintFloatPrecision) {
741 unittest::TestAllTypes message;
742
743 message.add_repeated_float(1.2);
744 message.add_repeated_float(1.23);
745 message.add_repeated_float(1.234);
746 message.add_repeated_float(1.2345);
747 message.add_repeated_float(1.23456);
748 message.add_repeated_float(1.2e10);
749 message.add_repeated_float(1.23e10);
750 message.add_repeated_float(1.234e10);
751 message.add_repeated_float(1.2345e10);
752 message.add_repeated_float(1.23456e10);
753 message.add_repeated_double(1.2);
754 message.add_repeated_double(1.23);
755 message.add_repeated_double(1.234);
756 message.add_repeated_double(1.2345);
757 message.add_repeated_double(1.23456);
758 message.add_repeated_double(1.234567);
759 message.add_repeated_double(1.2345678);
760 message.add_repeated_double(1.23456789);
761 message.add_repeated_double(1.234567898);
762 message.add_repeated_double(1.2345678987);
763 message.add_repeated_double(1.23456789876);
764 message.add_repeated_double(1.234567898765);
765 message.add_repeated_double(1.2345678987654);
766 message.add_repeated_double(1.23456789876543);
767 message.add_repeated_double(1.2e100);
768 message.add_repeated_double(1.23e100);
769 message.add_repeated_double(1.234e100);
770 message.add_repeated_double(1.2345e100);
771 message.add_repeated_double(1.23456e100);
772 message.add_repeated_double(1.234567e100);
773 message.add_repeated_double(1.2345678e100);
774 message.add_repeated_double(1.23456789e100);
775 message.add_repeated_double(1.234567898e100);
776 message.add_repeated_double(1.2345678987e100);
777 message.add_repeated_double(1.23456789876e100);
778 message.add_repeated_double(1.234567898765e100);
779 message.add_repeated_double(1.2345678987654e100);
780 message.add_repeated_double(1.23456789876543e100);
781
782 EXPECT_EQ(
783 "repeated_float: 1.2\n"
784 "repeated_float: 1.23\n"
785 "repeated_float: 1.234\n"
786 "repeated_float: 1.2345\n"
787 "repeated_float: 1.23456\n"
788 "repeated_float: 1.2e+10\n"
789 "repeated_float: 1.23e+10\n"
790 "repeated_float: 1.234e+10\n"
791 "repeated_float: 1.2345e+10\n"
792 "repeated_float: 1.23456e+10\n"
793 "repeated_double: 1.2\n"
794 "repeated_double: 1.23\n"
795 "repeated_double: 1.234\n"
796 "repeated_double: 1.2345\n"
797 "repeated_double: 1.23456\n"
798 "repeated_double: 1.234567\n"
799 "repeated_double: 1.2345678\n"
800 "repeated_double: 1.23456789\n"
801 "repeated_double: 1.234567898\n"
802 "repeated_double: 1.2345678987\n"
803 "repeated_double: 1.23456789876\n"
804 "repeated_double: 1.234567898765\n"
805 "repeated_double: 1.2345678987654\n"
806 "repeated_double: 1.23456789876543\n"
807 "repeated_double: 1.2e+100\n"
808 "repeated_double: 1.23e+100\n"
809 "repeated_double: 1.234e+100\n"
810 "repeated_double: 1.2345e+100\n"
811 "repeated_double: 1.23456e+100\n"
812 "repeated_double: 1.234567e+100\n"
813 "repeated_double: 1.2345678e+100\n"
814 "repeated_double: 1.23456789e+100\n"
815 "repeated_double: 1.234567898e+100\n"
816 "repeated_double: 1.2345678987e+100\n"
817 "repeated_double: 1.23456789876e+100\n"
818 "repeated_double: 1.234567898765e+100\n"
819 "repeated_double: 1.2345678987654e+100\n"
820 "repeated_double: 1.23456789876543e+100\n",
821 RemoveRedundantZeros(message.DebugString()));
822 }
823
824
TEST_F(TextFormatTest,AllowPartial)825 TEST_F(TextFormatTest, AllowPartial) {
826 unittest::TestRequired message;
827 TextFormat::Parser parser;
828 parser.AllowPartialMessage(true);
829 EXPECT_TRUE(parser.ParseFromString("a: 1", &message));
830 EXPECT_EQ(1, message.a());
831 EXPECT_FALSE(message.has_b());
832 EXPECT_FALSE(message.has_c());
833 }
834
TEST_F(TextFormatTest,ParseExotic)835 TEST_F(TextFormatTest, ParseExotic) {
836 unittest::TestAllTypes message;
837 ASSERT_TRUE(TextFormat::ParseFromString(
838 "repeated_int32: -1\n"
839 "repeated_int32: -2147483648\n"
840 "repeated_int64: -1\n"
841 "repeated_int64: -9223372036854775808\n"
842 "repeated_uint32: 4294967295\n"
843 "repeated_uint32: 2147483648\n"
844 "repeated_uint64: 18446744073709551615\n"
845 "repeated_uint64: 9223372036854775808\n"
846 "repeated_double: 123.0\n"
847 "repeated_double: 123.5\n"
848 "repeated_double: 0.125\n"
849 "repeated_double: 1.23E17\n"
850 "repeated_double: 1.235E+22\n"
851 "repeated_double: 1.235e-18\n"
852 "repeated_double: 123.456789\n"
853 "repeated_double: inf\n"
854 "repeated_double: Infinity\n"
855 "repeated_double: -inf\n"
856 "repeated_double: -Infinity\n"
857 "repeated_double: nan\n"
858 "repeated_double: NaN\n"
859 "repeated_string: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\"\n",
860 &message));
861
862 ASSERT_EQ(2, message.repeated_int32_size());
863 EXPECT_EQ(-1, message.repeated_int32(0));
864 // Note: In C, a negative integer literal is actually the unary negation
865 // operator being applied to a positive integer literal, and 2147483648 is
866 // outside the range of int32. However, it is not outside the range of
867 // uint32. Confusingly, this means that everything works if we make the
868 // literal unsigned, even though we are negating it.
869 EXPECT_EQ(-2147483648u, message.repeated_int32(1));
870
871 ASSERT_EQ(2, message.repeated_int64_size());
872 EXPECT_EQ(-1, message.repeated_int64(0));
873 // Note: In C, a negative integer literal is actually the unary negation
874 // operator being applied to a positive integer literal, and
875 // 9223372036854775808 is outside the range of int64. However, it is not
876 // outside the range of uint64. Confusingly, this means that everything
877 // works if we make the literal unsigned, even though we are negating it.
878 EXPECT_EQ(-GOOGLE_ULONGLONG(9223372036854775808), message.repeated_int64(1));
879
880 ASSERT_EQ(2, message.repeated_uint32_size());
881 EXPECT_EQ(4294967295u, message.repeated_uint32(0));
882 EXPECT_EQ(2147483648u, message.repeated_uint32(1));
883
884 ASSERT_EQ(2, message.repeated_uint64_size());
885 EXPECT_EQ(GOOGLE_ULONGLONG(18446744073709551615), message.repeated_uint64(0));
886 EXPECT_EQ(GOOGLE_ULONGLONG(9223372036854775808), message.repeated_uint64(1));
887
888 ASSERT_EQ(13, message.repeated_double_size());
889 EXPECT_EQ(123.0 , message.repeated_double(0));
890 EXPECT_EQ(123.5 , message.repeated_double(1));
891 EXPECT_EQ(0.125 , message.repeated_double(2));
892 EXPECT_EQ(1.23E17 , message.repeated_double(3));
893 EXPECT_EQ(1.235E22 , message.repeated_double(4));
894 EXPECT_EQ(1.235E-18 , message.repeated_double(5));
895 EXPECT_EQ(123.456789, message.repeated_double(6));
896 EXPECT_EQ(message.repeated_double(7), numeric_limits<double>::infinity());
897 EXPECT_EQ(message.repeated_double(8), numeric_limits<double>::infinity());
898 EXPECT_EQ(message.repeated_double(9), -numeric_limits<double>::infinity());
899 EXPECT_EQ(message.repeated_double(10), -numeric_limits<double>::infinity());
900 EXPECT_TRUE(IsNaN(message.repeated_double(11)));
901 EXPECT_TRUE(IsNaN(message.repeated_double(12)));
902
903 // Note: Since these string literals have \0's in them, we must explicitly
904 // pass their sizes to string's constructor.
905 ASSERT_EQ(1, message.repeated_string_size());
906 EXPECT_EQ(string("\000\001\a\b\f\n\r\t\v\\\'\"", 12),
907 message.repeated_string(0));
908 }
909
TEST_F(TextFormatTest,PrintFieldsInIndexOrder)910 TEST_F(TextFormatTest, PrintFieldsInIndexOrder) {
911 protobuf_unittest::TestFieldOrderings message;
912 // Fields are listed in index order instead of field number.
913 message.set_my_string("Test String"); // Field number 11
914 message.set_my_int(12345); // Field number 1
915 message.set_my_float(0.999); // Field number 101
916 TextFormat::Printer printer;
917 string text;
918
919 // By default, print in field number order.
920 printer.PrintToString(message, &text);
921 EXPECT_EQ("my_int: 12345\nmy_string: \"Test String\"\nmy_float: 0.999\n",
922 text);
923
924 // Print in index order.
925 printer.SetPrintMessageFieldsInIndexOrder(true);
926 printer.PrintToString(message, &text);
927 EXPECT_EQ("my_string: \"Test String\"\nmy_int: 12345\nmy_float: 0.999\n",
928 text);
929 }
930
931 class TextFormatParserTest : public testing::Test {
932 protected:
ExpectFailure(const string & input,const string & message,int line,int col)933 void ExpectFailure(const string& input, const string& message, int line,
934 int col) {
935 scoped_ptr<unittest::TestAllTypes> proto(new unittest::TestAllTypes);
936 ExpectFailure(input, message, line, col, proto.get());
937 }
938
ExpectFailure(const string & input,const string & message,int line,int col,Message * proto)939 void ExpectFailure(const string& input, const string& message, int line,
940 int col, Message* proto) {
941 ExpectMessage(input, message, line, col, proto, false);
942 }
943
ExpectMessage(const string & input,const string & message,int line,int col,Message * proto,bool expected_result)944 void ExpectMessage(const string& input, const string& message, int line,
945 int col, Message* proto, bool expected_result) {
946 TextFormat::Parser parser;
947 MockErrorCollector error_collector;
948 parser.RecordErrorsTo(&error_collector);
949 EXPECT_EQ(expected_result, parser.ParseFromString(input, proto))
950 << input << " -> " << proto->DebugString();
951 EXPECT_EQ(SimpleItoa(line) + ":" + SimpleItoa(col) + ": " + message + "\n",
952 error_collector.text_);
953 }
954
ExpectSuccessAndTree(const string & input,Message * proto,TextFormat::ParseInfoTree * info_tree)955 void ExpectSuccessAndTree(const string& input, Message* proto,
956 TextFormat::ParseInfoTree* info_tree) {
957 TextFormat::Parser parser;
958 MockErrorCollector error_collector;
959 parser.RecordErrorsTo(&error_collector);
960 parser.WriteLocationsTo(info_tree);
961
962 EXPECT_TRUE(parser.ParseFromString(input, proto));
963 }
964
ExpectLocation(TextFormat::ParseInfoTree * tree,const Descriptor * d,const string & field_name,int index,int line,int column)965 void ExpectLocation(TextFormat::ParseInfoTree* tree,
966 const Descriptor* d, const string& field_name,
967 int index, int line, int column) {
968 TextFormat::ParseLocation location = tree->GetLocation(
969 d->FindFieldByName(field_name), index);
970 EXPECT_EQ(line, location.line);
971 EXPECT_EQ(column, location.column);
972 }
973
974 // An error collector which simply concatenates all its errors into a big
975 // block of text which can be checked.
976 class MockErrorCollector : public io::ErrorCollector {
977 public:
MockErrorCollector()978 MockErrorCollector() {}
~MockErrorCollector()979 ~MockErrorCollector() {}
980
981 string text_;
982
983 // implements ErrorCollector -------------------------------------
AddError(int line,int column,const string & message)984 void AddError(int line, int column, const string& message) {
985 strings::SubstituteAndAppend(&text_, "$0:$1: $2\n",
986 line + 1, column + 1, message);
987 }
988
AddWarning(int line,int column,const string & message)989 void AddWarning(int line, int column, const string& message) {
990 AddError(line, column, "WARNING:" + message);
991 }
992 };
993 };
994
TEST_F(TextFormatParserTest,ParseInfoTreeBuilding)995 TEST_F(TextFormatParserTest, ParseInfoTreeBuilding) {
996 scoped_ptr<unittest::TestAllTypes> message(new unittest::TestAllTypes);
997 const Descriptor* d = message->GetDescriptor();
998
999 string stringData =
1000 "optional_int32: 1\n"
1001 "optional_int64: 2\n"
1002 " optional_double: 2.4\n"
1003 "repeated_int32: 5\n"
1004 "repeated_int32: 10\n"
1005 "optional_nested_message <\n"
1006 " bb: 78\n"
1007 ">\n"
1008 "repeated_nested_message <\n"
1009 " bb: 79\n"
1010 ">\n"
1011 "repeated_nested_message <\n"
1012 " bb: 80\n"
1013 ">";
1014
1015
1016 TextFormat::ParseInfoTree tree;
1017 ExpectSuccessAndTree(stringData, message.get(), &tree);
1018
1019 // Verify that the tree has the correct positions.
1020 ExpectLocation(&tree, d, "optional_int32", -1, 0, 0);
1021 ExpectLocation(&tree, d, "optional_int64", -1, 1, 0);
1022 ExpectLocation(&tree, d, "optional_double", -1, 2, 2);
1023
1024 ExpectLocation(&tree, d, "repeated_int32", 0, 3, 0);
1025 ExpectLocation(&tree, d, "repeated_int32", 1, 4, 0);
1026
1027 ExpectLocation(&tree, d, "optional_nested_message", -1, 5, 0);
1028 ExpectLocation(&tree, d, "repeated_nested_message", 0, 8, 0);
1029 ExpectLocation(&tree, d, "repeated_nested_message", 1, 11, 0);
1030
1031 // Check for fields not set. For an invalid field, the location returned
1032 // should be -1, -1.
1033 ExpectLocation(&tree, d, "repeated_int64", 0, -1, -1);
1034 ExpectLocation(&tree, d, "repeated_int32", 6, -1, -1);
1035 ExpectLocation(&tree, d, "some_unknown_field", -1, -1, -1);
1036
1037 // Verify inside the nested message.
1038 const FieldDescriptor* nested_field =
1039 d->FindFieldByName("optional_nested_message");
1040
1041 TextFormat::ParseInfoTree* nested_tree =
1042 tree.GetTreeForNested(nested_field, -1);
1043 ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 6, 2);
1044
1045 // Verify inside another nested message.
1046 nested_field = d->FindFieldByName("repeated_nested_message");
1047 nested_tree = tree.GetTreeForNested(nested_field, 0);
1048 ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 9, 2);
1049
1050 nested_tree = tree.GetTreeForNested(nested_field, 1);
1051 ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 12, 2);
1052
1053 // Verify a NULL tree for an unknown nested field.
1054 TextFormat::ParseInfoTree* unknown_nested_tree =
1055 tree.GetTreeForNested(nested_field, 2);
1056
1057 EXPECT_EQ(NULL, unknown_nested_tree);
1058 }
1059
TEST_F(TextFormatParserTest,ParseFieldValueFromString)1060 TEST_F(TextFormatParserTest, ParseFieldValueFromString) {
1061 scoped_ptr<unittest::TestAllTypes> message(new unittest::TestAllTypes);
1062 const Descriptor* d = message->GetDescriptor();
1063
1064 #define EXPECT_FIELD(name, value, valuestring) \
1065 EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
1066 valuestring, d->FindFieldByName("optional_" #name), message.get())); \
1067 EXPECT_EQ(value, message->optional_##name()); \
1068 EXPECT_TRUE(message->has_optional_##name());
1069
1070 #define EXPECT_BOOL_FIELD(name, value, valuestring) \
1071 EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
1072 valuestring, d->FindFieldByName("optional_" #name), message.get())); \
1073 EXPECT_TRUE(message->optional_##name() == value); \
1074 EXPECT_TRUE(message->has_optional_##name());
1075
1076 #define EXPECT_FLOAT_FIELD(name, value, valuestring) \
1077 EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
1078 valuestring, d->FindFieldByName("optional_" #name), message.get())); \
1079 EXPECT_FLOAT_EQ(value, message->optional_##name()); \
1080 EXPECT_TRUE(message->has_optional_##name());
1081
1082 #define EXPECT_DOUBLE_FIELD(name, value, valuestring) \
1083 EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
1084 valuestring, d->FindFieldByName("optional_" #name), message.get())); \
1085 EXPECT_DOUBLE_EQ(value, message->optional_##name()); \
1086 EXPECT_TRUE(message->has_optional_##name());
1087
1088 #define EXPECT_INVALID(name, valuestring) \
1089 EXPECT_FALSE(TextFormat::ParseFieldValueFromString( \
1090 valuestring, d->FindFieldByName("optional_" #name), message.get()));
1091
1092 // int32
1093 EXPECT_FIELD(int32, 1, "1");
1094 EXPECT_FIELD(int32, -1, "-1");
1095 EXPECT_FIELD(int32, 0x1234, "0x1234");
1096 EXPECT_INVALID(int32, "a");
1097 EXPECT_INVALID(int32, "999999999999999999999999999999999999");
1098 EXPECT_INVALID(int32, "1,2");
1099
1100 // int64
1101 EXPECT_FIELD(int64, 1, "1");
1102 EXPECT_FIELD(int64, -1, "-1");
1103 EXPECT_FIELD(int64, 0x1234567812345678LL, "0x1234567812345678");
1104 EXPECT_INVALID(int64, "a");
1105 EXPECT_INVALID(int64, "999999999999999999999999999999999999");
1106 EXPECT_INVALID(int64, "1,2");
1107
1108 // uint64
1109 EXPECT_FIELD(uint64, 1, "1");
1110 EXPECT_FIELD(uint64, 0xf234567812345678ULL, "0xf234567812345678");
1111 EXPECT_INVALID(uint64, "-1");
1112 EXPECT_INVALID(uint64, "a");
1113 EXPECT_INVALID(uint64, "999999999999999999999999999999999999");
1114 EXPECT_INVALID(uint64, "1,2");
1115
1116 // fixed32
1117 EXPECT_FIELD(fixed32, 1, "1");
1118 EXPECT_FIELD(fixed32, 0x12345678, "0x12345678");
1119 EXPECT_INVALID(fixed32, "-1");
1120 EXPECT_INVALID(fixed32, "a");
1121 EXPECT_INVALID(fixed32, "999999999999999999999999999999999999");
1122 EXPECT_INVALID(fixed32, "1,2");
1123
1124 // fixed64
1125 EXPECT_FIELD(fixed64, 1, "1");
1126 EXPECT_FIELD(fixed64, 0x1234567812345678ULL, "0x1234567812345678");
1127 EXPECT_INVALID(fixed64, "-1");
1128 EXPECT_INVALID(fixed64, "a");
1129 EXPECT_INVALID(fixed64, "999999999999999999999999999999999999");
1130 EXPECT_INVALID(fixed64, "1,2");
1131
1132 // bool
1133 EXPECT_BOOL_FIELD(bool, true, "true");
1134 EXPECT_BOOL_FIELD(bool, false, "false");
1135 EXPECT_BOOL_FIELD(bool, true, "1");
1136 EXPECT_BOOL_FIELD(bool, true, "t");
1137 EXPECT_BOOL_FIELD(bool, false, "0");
1138 EXPECT_BOOL_FIELD(bool, false, "f");
1139 EXPECT_FIELD(bool, true, "True");
1140 EXPECT_FIELD(bool, false, "False");
1141 EXPECT_INVALID(bool, "tRue");
1142 EXPECT_INVALID(bool, "faLse");
1143 EXPECT_INVALID(bool, "2");
1144 EXPECT_INVALID(bool, "-0");
1145 EXPECT_INVALID(bool, "on");
1146 EXPECT_INVALID(bool, "a");
1147
1148 // float
1149 EXPECT_FIELD(float, 1, "1");
1150 EXPECT_FLOAT_FIELD(float, 1.5, "1.5");
1151 EXPECT_FLOAT_FIELD(float, 1.5e3, "1.5e3");
1152 EXPECT_FLOAT_FIELD(float, -4.55, "-4.55");
1153 EXPECT_INVALID(float, "a");
1154 EXPECT_INVALID(float, "1,2");
1155
1156 // double
1157 EXPECT_FIELD(double, 1, "1");
1158 EXPECT_FIELD(double, -1, "-1");
1159 EXPECT_DOUBLE_FIELD(double, 2.3, "2.3");
1160 EXPECT_DOUBLE_FIELD(double, 3e5, "3e5");
1161 EXPECT_INVALID(double, "a");
1162 EXPECT_INVALID(double, "1,2");
1163 // Rejects hex and oct numbers for a double field.
1164 EXPECT_INVALID(double, "0xf");
1165 EXPECT_INVALID(double, "012");
1166
1167 // string
1168 EXPECT_FIELD(string, "hello", "\"hello\"");
1169 EXPECT_FIELD(string, "-1.87", "'-1.87'");
1170 EXPECT_INVALID(string, "hello"); // without quote for value
1171
1172 // enum
1173 EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAR, "BAR");
1174 EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAZ,
1175 SimpleItoa(unittest::TestAllTypes::BAZ));
1176 EXPECT_INVALID(nested_enum, "FOOBAR");
1177
1178 // message
1179 EXPECT_TRUE(TextFormat::ParseFieldValueFromString(
1180 "<bb:12>", d->FindFieldByName("optional_nested_message"), message.get()));
1181 EXPECT_EQ(12, message->optional_nested_message().bb()); \
1182 EXPECT_TRUE(message->has_optional_nested_message());
1183 EXPECT_INVALID(nested_message, "any");
1184
1185 #undef EXPECT_FIELD
1186 #undef EXPECT_BOOL_FIELD
1187 #undef EXPECT_FLOAT_FIELD
1188 #undef EXPECT_DOUBLE_FIELD
1189 #undef EXPECT_INVALID
1190 }
1191
1192
TEST_F(TextFormatParserTest,InvalidToken)1193 TEST_F(TextFormatParserTest, InvalidToken) {
1194 ExpectFailure("optional_bool: true\n-5\n", "Expected identifier.",
1195 2, 1);
1196
1197 ExpectFailure("optional_bool: true!\n", "Expected identifier.", 1, 20);
1198 ExpectFailure("\"some string\"", "Expected identifier.", 1, 1);
1199 }
1200
TEST_F(TextFormatParserTest,InvalidFieldName)1201 TEST_F(TextFormatParserTest, InvalidFieldName) {
1202 ExpectFailure(
1203 "invalid_field: somevalue\n",
1204 "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
1205 "\"invalid_field\".",
1206 1, 14);
1207 }
1208
TEST_F(TextFormatParserTest,InvalidCapitalization)1209 TEST_F(TextFormatParserTest, InvalidCapitalization) {
1210 // We require that group names be exactly as they appear in the .proto.
1211 ExpectFailure(
1212 "optionalgroup {\na: 15\n}\n",
1213 "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
1214 "\"optionalgroup\".",
1215 1, 15);
1216 ExpectFailure(
1217 "OPTIONALgroup {\na: 15\n}\n",
1218 "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
1219 "\"OPTIONALgroup\".",
1220 1, 15);
1221 ExpectFailure(
1222 "Optional_Double: 10.0\n",
1223 "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
1224 "\"Optional_Double\".",
1225 1, 16);
1226 }
1227
TEST_F(TextFormatParserTest,AllowIgnoreCapitalizationError)1228 TEST_F(TextFormatParserTest, AllowIgnoreCapitalizationError) {
1229 TextFormat::Parser parser;
1230 protobuf_unittest::TestAllTypes proto;
1231
1232 // These fields have a mismatching case.
1233 EXPECT_FALSE(parser.ParseFromString("Optional_Double: 10.0", &proto));
1234 EXPECT_FALSE(parser.ParseFromString("oPtIoNaLgRoUp { a: 15 }", &proto));
1235
1236 // ... but are parsed correctly if we match case insensitive.
1237 parser.AllowCaseInsensitiveField(true);
1238 EXPECT_TRUE(parser.ParseFromString("Optional_Double: 10.0", &proto));
1239 EXPECT_EQ(10.0, proto.optional_double());
1240 EXPECT_TRUE(parser.ParseFromString("oPtIoNaLgRoUp { a: 15 }", &proto));
1241 EXPECT_EQ(15, proto.optionalgroup().a());
1242 }
1243
TEST_F(TextFormatParserTest,InvalidFieldValues)1244 TEST_F(TextFormatParserTest, InvalidFieldValues) {
1245 // Invalid values for a double/float field.
1246 ExpectFailure("optional_double: \"hello\"\n", "Expected double.", 1, 18);
1247 ExpectFailure("optional_double: true\n", "Expected double.", 1, 18);
1248 ExpectFailure("optional_double: !\n", "Expected double.", 1, 18);
1249 ExpectFailure("optional_double {\n \n}\n", "Expected \":\", found \"{\".",
1250 1, 17);
1251
1252 // Invalid values for a signed integer field.
1253 ExpectFailure("optional_int32: \"hello\"\n", "Expected integer.", 1, 17);
1254 ExpectFailure("optional_int32: true\n", "Expected integer.", 1, 17);
1255 ExpectFailure("optional_int32: 4.5\n", "Expected integer.", 1, 17);
1256 ExpectFailure("optional_int32: !\n", "Expected integer.", 1, 17);
1257 ExpectFailure("optional_int32 {\n \n}\n", "Expected \":\", found \"{\".",
1258 1, 16);
1259 ExpectFailure("optional_int32: 0x80000000\n",
1260 "Integer out of range.", 1, 17);
1261 ExpectFailure("optional_int64: 0x8000000000000000\n",
1262 "Integer out of range.", 1, 17);
1263 ExpectFailure("optional_int32: -0x80000001\n",
1264 "Integer out of range.", 1, 18);
1265 ExpectFailure("optional_int64: -0x8000000000000001\n",
1266 "Integer out of range.", 1, 18);
1267
1268 // Invalid values for an unsigned integer field.
1269 ExpectFailure("optional_uint64: \"hello\"\n", "Expected integer.", 1, 18);
1270 ExpectFailure("optional_uint64: true\n", "Expected integer.", 1, 18);
1271 ExpectFailure("optional_uint64: 4.5\n", "Expected integer.", 1, 18);
1272 ExpectFailure("optional_uint64: -5\n", "Expected integer.", 1, 18);
1273 ExpectFailure("optional_uint64: !\n", "Expected integer.", 1, 18);
1274 ExpectFailure("optional_uint64 {\n \n}\n", "Expected \":\", found \"{\".",
1275 1, 17);
1276 ExpectFailure("optional_uint32: 0x100000000\n",
1277 "Integer out of range.", 1, 18);
1278 ExpectFailure("optional_uint64: 0x10000000000000000\n",
1279 "Integer out of range.", 1, 18);
1280
1281 // Invalid values for a boolean field.
1282 ExpectFailure("optional_bool: \"hello\"\n", "Expected identifier.", 1, 16);
1283 ExpectFailure("optional_bool: 5\n", "Integer out of range.", 1, 16);
1284 ExpectFailure("optional_bool: -7.5\n", "Expected identifier.", 1, 16);
1285 ExpectFailure("optional_bool: !\n", "Expected identifier.", 1, 16);
1286
1287 ExpectFailure(
1288 "optional_bool: meh\n",
1289 "Invalid value for boolean field \"optional_bool\". Value: \"meh\".",
1290 2, 1);
1291
1292 ExpectFailure("optional_bool {\n \n}\n", "Expected \":\", found \"{\".",
1293 1, 15);
1294
1295 // Invalid values for a string field.
1296 ExpectFailure("optional_string: true\n", "Expected string.", 1, 18);
1297 ExpectFailure("optional_string: 5\n", "Expected string.", 1, 18);
1298 ExpectFailure("optional_string: -7.5\n", "Expected string.", 1, 18);
1299 ExpectFailure("optional_string: !\n", "Expected string.", 1, 18);
1300 ExpectFailure("optional_string {\n \n}\n", "Expected \":\", found \"{\".",
1301 1, 17);
1302
1303 // Invalid values for an enumeration field.
1304 ExpectFailure("optional_nested_enum: \"hello\"\n",
1305 "Expected integer or identifier.", 1, 23);
1306
1307 // Valid token, but enum value is not defined.
1308 ExpectFailure("optional_nested_enum: 5\n",
1309 "Unknown enumeration value of \"5\" for field "
1310 "\"optional_nested_enum\".", 2, 1);
1311 // We consume the negative sign, so the error position starts one character
1312 // later.
1313 ExpectFailure("optional_nested_enum: -7.5\n", "Expected integer.", 1, 24);
1314 ExpectFailure("optional_nested_enum: !\n",
1315 "Expected integer or identifier.", 1, 23);
1316
1317 ExpectFailure(
1318 "optional_nested_enum: grah\n",
1319 "Unknown enumeration value of \"grah\" for field "
1320 "\"optional_nested_enum\".", 2, 1);
1321
1322 ExpectFailure(
1323 "optional_nested_enum {\n \n}\n",
1324 "Expected \":\", found \"{\".", 1, 22);
1325 }
1326
TEST_F(TextFormatParserTest,MessageDelimeters)1327 TEST_F(TextFormatParserTest, MessageDelimeters) {
1328 // Non-matching delimeters.
1329 ExpectFailure("OptionalGroup <\n \n}\n", "Expected \">\", found \"}\".",
1330 3, 1);
1331
1332 // Invalid delimeters.
1333 ExpectFailure("OptionalGroup [\n \n]\n", "Expected \"{\", found \"[\".",
1334 1, 15);
1335
1336 // Unending message.
1337 ExpectFailure("optional_nested_message {\n \nbb: 118\n",
1338 "Expected identifier.",
1339 4, 1);
1340 }
1341
TEST_F(TextFormatParserTest,UnknownExtension)1342 TEST_F(TextFormatParserTest, UnknownExtension) {
1343 // Non-matching delimeters.
1344 ExpectFailure("[blahblah]: 123",
1345 "Extension \"blahblah\" is not defined or is not an "
1346 "extension of \"protobuf_unittest.TestAllTypes\".",
1347 1, 11);
1348 }
1349
TEST_F(TextFormatParserTest,MissingRequired)1350 TEST_F(TextFormatParserTest, MissingRequired) {
1351 unittest::TestRequired message;
1352 ExpectFailure("a: 1",
1353 "Message missing required fields: b, c",
1354 0, 1, &message);
1355 }
1356
TEST_F(TextFormatParserTest,ParseDuplicateRequired)1357 TEST_F(TextFormatParserTest, ParseDuplicateRequired) {
1358 unittest::TestRequired message;
1359 ExpectFailure("a: 1 b: 2 c: 3 a: 1",
1360 "Non-repeated field \"a\" is specified multiple times.",
1361 1, 17, &message);
1362 }
1363
TEST_F(TextFormatParserTest,ParseDuplicateOptional)1364 TEST_F(TextFormatParserTest, ParseDuplicateOptional) {
1365 unittest::ForeignMessage message;
1366 ExpectFailure("c: 1 c: 2",
1367 "Non-repeated field \"c\" is specified multiple times.",
1368 1, 7, &message);
1369 }
1370
TEST_F(TextFormatParserTest,MergeDuplicateRequired)1371 TEST_F(TextFormatParserTest, MergeDuplicateRequired) {
1372 unittest::TestRequired message;
1373 TextFormat::Parser parser;
1374 EXPECT_TRUE(parser.MergeFromString("a: 1 b: 2 c: 3 a: 4", &message));
1375 EXPECT_EQ(4, message.a());
1376 }
1377
TEST_F(TextFormatParserTest,MergeDuplicateOptional)1378 TEST_F(TextFormatParserTest, MergeDuplicateOptional) {
1379 unittest::ForeignMessage message;
1380 TextFormat::Parser parser;
1381 EXPECT_TRUE(parser.MergeFromString("c: 1 c: 2", &message));
1382 EXPECT_EQ(2, message.c());
1383 }
1384
TEST_F(TextFormatParserTest,ExplicitDelimiters)1385 TEST_F(TextFormatParserTest, ExplicitDelimiters) {
1386 unittest::TestRequired message;
1387 EXPECT_TRUE(TextFormat::ParseFromString("a:1,b:2;c:3", &message));
1388 EXPECT_EQ(1, message.a());
1389 EXPECT_EQ(2, message.b());
1390 EXPECT_EQ(3, message.c());
1391 }
1392
TEST_F(TextFormatParserTest,PrintErrorsToStderr)1393 TEST_F(TextFormatParserTest, PrintErrorsToStderr) {
1394 vector<string> errors;
1395
1396 {
1397 ScopedMemoryLog log;
1398 unittest::TestAllTypes proto;
1399 EXPECT_FALSE(TextFormat::ParseFromString("no_such_field: 1", &proto));
1400 errors = log.GetMessages(ERROR);
1401 }
1402
1403 ASSERT_EQ(1, errors.size());
1404 EXPECT_EQ("Error parsing text-format protobuf_unittest.TestAllTypes: "
1405 "1:14: Message type \"protobuf_unittest.TestAllTypes\" has no field "
1406 "named \"no_such_field\".",
1407 errors[0]);
1408 }
1409
TEST_F(TextFormatParserTest,FailsOnTokenizationError)1410 TEST_F(TextFormatParserTest, FailsOnTokenizationError) {
1411 vector<string> errors;
1412
1413 {
1414 ScopedMemoryLog log;
1415 unittest::TestAllTypes proto;
1416 EXPECT_FALSE(TextFormat::ParseFromString("\020", &proto));
1417 errors = log.GetMessages(ERROR);
1418 }
1419
1420 ASSERT_EQ(1, errors.size());
1421 EXPECT_EQ("Error parsing text-format protobuf_unittest.TestAllTypes: "
1422 "1:1: Invalid control characters encountered in text.",
1423 errors[0]);
1424 }
1425
TEST_F(TextFormatParserTest,ParseDeprecatedField)1426 TEST_F(TextFormatParserTest, ParseDeprecatedField) {
1427 unittest::TestDeprecatedFields message;
1428 ExpectMessage("deprecated_int32: 42",
1429 "WARNING:text format contains deprecated field "
1430 "\"deprecated_int32\"", 1, 21, &message, true);
1431 }
1432
1433 class TextFormatMessageSetTest : public testing::Test {
1434 protected:
1435 static const char proto_debug_string_[];
1436 };
1437 const char TextFormatMessageSetTest::proto_debug_string_[] =
1438 "message_set {\n"
1439 " [protobuf_unittest.TestMessageSetExtension1] {\n"
1440 " i: 23\n"
1441 " }\n"
1442 " [protobuf_unittest.TestMessageSetExtension2] {\n"
1443 " str: \"foo\"\n"
1444 " }\n"
1445 "}\n";
1446
1447
TEST_F(TextFormatMessageSetTest,Serialize)1448 TEST_F(TextFormatMessageSetTest, Serialize) {
1449 protobuf_unittest::TestMessageSetContainer proto;
1450 protobuf_unittest::TestMessageSetExtension1* item_a =
1451 proto.mutable_message_set()->MutableExtension(
1452 protobuf_unittest::TestMessageSetExtension1::message_set_extension);
1453 item_a->set_i(23);
1454 protobuf_unittest::TestMessageSetExtension2* item_b =
1455 proto.mutable_message_set()->MutableExtension(
1456 protobuf_unittest::TestMessageSetExtension2::message_set_extension);
1457 item_b->set_str("foo");
1458 EXPECT_EQ(proto_debug_string_, proto.DebugString());
1459 }
1460
TEST_F(TextFormatMessageSetTest,Deserialize)1461 TEST_F(TextFormatMessageSetTest, Deserialize) {
1462 protobuf_unittest::TestMessageSetContainer proto;
1463 ASSERT_TRUE(TextFormat::ParseFromString(proto_debug_string_, &proto));
1464 EXPECT_EQ(23, proto.message_set().GetExtension(
1465 protobuf_unittest::TestMessageSetExtension1::message_set_extension).i());
1466 EXPECT_EQ("foo", proto.message_set().GetExtension(
1467 protobuf_unittest::TestMessageSetExtension2::message_set_extension).str());
1468
1469 // Ensure that these are the only entries present.
1470 vector<const FieldDescriptor*> descriptors;
1471 proto.message_set().GetReflection()->ListFields(
1472 proto.message_set(), &descriptors);
1473 EXPECT_EQ(2, descriptors.size());
1474 }
1475
1476
1477 } // namespace text_format_unittest
1478 } // namespace protobuf
1479 } // namespace google
1480