blob: ac4efc941a4c933f3aa66e8fc80929ea2c7817a7 [file] [log] [blame]
temporal40ee5512008-07-10 02:12:20 +00001// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc.
3// http://code.google.com/p/protobuf/
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17// Author: jschorr@google.com (Joseph Schorr)
18// Based on original Protocol Buffers design by
19// Sanjay Ghemawat, Jeff Dean, and others.
20
21#include <math.h>
22#include <stdlib.h>
23#include <limits>
24
25#include <google/protobuf/text_format.h>
26#include <google/protobuf/io/zero_copy_stream_impl.h>
27#include <google/protobuf/io/tokenizer.h>
28#include <google/protobuf/unittest.pb.h>
29#include <google/protobuf/unittest_mset.pb.h>
30#include <google/protobuf/test_util.h>
31
32#include <google/protobuf/stubs/common.h>
33#include <google/protobuf/testing/file.h>
34#include <google/protobuf/testing/googletest.h>
35#include <gtest/gtest.h>
36#include <google/protobuf/stubs/strutil.h>
37#include <google/protobuf/stubs/substitute.h>
38
39namespace google {
40namespace protobuf {
41namespace {
42
43inline bool IsNaN(double value) {
44 // NaN is never equal to anything, even itself.
45 return value != value;
46}
47
48// A basic string with different escapable characters for testing.
49const string kEscapeTestString =
50 "\"A string with ' characters \n and \r newlines and \t tabs and \001 "
51 "slashes \\";
52
53// A representation of the above string with all the characters escaped.
54const string kEscapeTestStringEscaped =
55 "\"\\\"A string with \\' characters \\n and \\r newlines "
56 "and \\t tabs and \\001 slashes \\\\\"";
57
58class TextFormatTest : public testing::Test {
59 public:
60 static void SetUpTestCase() {
61 File::ReadFileToStringOrDie(
62 TestSourceDir()
63 + "/google/protobuf/testdata/text_format_unittest_data.txt",
64 &static_proto_debug_string_);
65 }
66
67 TextFormatTest() : proto_debug_string_(static_proto_debug_string_) {}
68
69 protected:
70 // Debug string read from text_format_unittest_data.txt.
71 const string proto_debug_string_;
72 unittest::TestAllTypes proto_;
73
74 private:
75 static string static_proto_debug_string_;
76};
77string TextFormatTest::static_proto_debug_string_;
78
79class TextFormatExtensionsTest : public testing::Test {
80 public:
81 static void SetUpTestCase() {
82 File::ReadFileToStringOrDie(
83 TestSourceDir()
84 + "/google/protobuf/testdata/"
85 "text_format_unittest_extensions_data.txt",
86 &static_proto_debug_string_);
87 }
88
89 TextFormatExtensionsTest()
90 : proto_debug_string_(static_proto_debug_string_) {}
91
92 protected:
93 // Debug string read from text_format_unittest_data.txt.
94 const string proto_debug_string_;
95 unittest::TestAllExtensions proto_;
96
97 private:
98 static string static_proto_debug_string_;
99};
100string TextFormatExtensionsTest::static_proto_debug_string_;
101
102
103TEST_F(TextFormatTest, Basic) {
104 TestUtil::SetAllFields(&proto_);
105 EXPECT_EQ(proto_debug_string_, proto_.DebugString());
106}
107
108TEST_F(TextFormatExtensionsTest, Extensions) {
109 TestUtil::SetAllExtensions(&proto_);
110 EXPECT_EQ(proto_debug_string_, proto_.DebugString());
111}
112
113TEST_F(TextFormatTest, StringEscape) {
114 // Set the string value to test.
115 proto_.set_optional_string(kEscapeTestString);
116
117 // Get the DebugString from the proto.
118 string debug_string = proto_.DebugString();
119
120 // Hardcode a correct value to test against.
121 string correct_string = "optional_string: "
122 + kEscapeTestStringEscaped
123 + "\n";
124
125 // Compare.
126 EXPECT_EQ(correct_string, debug_string);
127}
128
129TEST_F(TextFormatTest, PrintUnknownFields) {
130 // Test printing of unknown fields in a message.
131
132 unittest::TestEmptyMessage message;
133 UnknownFieldSet* unknown_fields = message.mutable_unknown_fields();
134 UnknownField* field5 = unknown_fields->AddField(5);
135
136 field5->add_varint(1);
137 field5->add_fixed32(2);
138 field5->add_fixed64(3);
139 field5->add_length_delimited("4");
140 field5->add_group()->AddField(10)->add_varint(5);
141
142 UnknownField* field8 = unknown_fields->AddField(8);
143 field8->add_varint(1);
144 field8->add_varint(2);
145 field8->add_varint(3);
146
147 EXPECT_EQ(
148 "5: 1\n"
149 "5: 0x00000002\n"
150 "5: 0x0000000000000003\n"
151 "5: \"4\"\n"
152 "5 {\n"
153 " 10: 5\n"
154 "}\n"
155 "8: 1\n"
156 "8: 2\n"
157 "8: 3\n",
158 message.DebugString());
159}
160
temporala0f27fc2008-08-06 01:12:21 +0000161TEST_F(TextFormatTest, PrintUnknownMessage) {
162 // Test heuristic printing of messages in an UnknownFieldSet.
163
164 protobuf_unittest::TestAllTypes message;
165
166 // Cases which should not be interpreted as sub-messages.
167
168 // 'a' is a valid FIXED64 tag, so for the string to be parseable as a message
169 // it should be followed by 8 bytes. Since this string only has two
170 // subsequent bytes, it should be treated as a string.
171 message.add_repeated_string("abc");
172
173 // 'd' happens to be a valid ENDGROUP tag. So,
174 // UnknownFieldSet::MergeFromCodedStream() will successfully parse "def", but
175 // the ConsumedEntireMessage() check should fail.
176 message.add_repeated_string("def");
177
178 // A zero-length string should never be interpreted as a message even though
179 // it is technically valid as one.
180 message.add_repeated_string("");
181
182 // Case which should be interpreted as a sub-message.
183
184 // An actual nested message with content should always be interpreted as a
185 // nested message.
186 message.add_repeated_nested_message()->set_bb(123);
187
188 string data;
189 message.SerializeToString(&data);
190
191 string text;
192 UnknownFieldSet unknown_fields;
193 EXPECT_TRUE(unknown_fields.ParseFromString(data));
194 EXPECT_TRUE(TextFormat::PrintUnknownFieldsToString(unknown_fields, &text));
195 EXPECT_EQ(
196 "44: \"abc\"\n"
197 "44: \"def\"\n"
198 "44: \"\"\n"
199 "48 {\n"
200 " 1: 123\n"
201 "}\n",
202 text);
203}
204
temporal40ee5512008-07-10 02:12:20 +0000205TEST_F(TextFormatTest, ParseBasic) {
206 io::ArrayInputStream input_stream(proto_debug_string_.data(),
207 proto_debug_string_.size());
208 TextFormat::Parse(&input_stream, &proto_);
209 TestUtil::ExpectAllFieldsSet(proto_);
210}
211
212TEST_F(TextFormatExtensionsTest, ParseExtensions) {
213 io::ArrayInputStream input_stream(proto_debug_string_.data(),
214 proto_debug_string_.size());
215 TextFormat::Parse(&input_stream, &proto_);
216 TestUtil::ExpectAllExtensionsSet(proto_);
217}
218
219TEST_F(TextFormatTest, ParseStringEscape) {
220 // Create a parse string with escpaed characters in it.
221 string parse_string = "optional_string: "
222 + kEscapeTestStringEscaped
223 + "\n";
224
225 io::ArrayInputStream input_stream(parse_string.data(),
226 parse_string.size());
227 TextFormat::Parse(&input_stream, &proto_);
228
229 // Compare.
230 EXPECT_EQ(kEscapeTestString, proto_.optional_string());
231}
232
233TEST_F(TextFormatTest, ParseFloatWithSuffix) {
234 // Test that we can parse a floating-point value with 'f' appended to the
235 // end. This is needed for backwards-compatibility with proto1.
236
237 // Have it parse a float with the 'f' suffix.
238 string parse_string = "optional_float: 1.0f\n";
239
240 io::ArrayInputStream input_stream(parse_string.data(),
241 parse_string.size());
242
243 TextFormat::Parse(&input_stream, &proto_);
244
245 // Compare.
246 EXPECT_EQ(1.0, proto_.optional_float());
247}
248
249TEST_F(TextFormatTest, Comments) {
250 // Test that comments are ignored.
251
252 string parse_string = "optional_int32: 1 # a comment\n"
253 "optional_int64: 2 # another comment";
254
255 io::ArrayInputStream input_stream(parse_string.data(),
256 parse_string.size());
257
258 TextFormat::Parse(&input_stream, &proto_);
259
260 // Compare.
261 EXPECT_EQ(1, proto_.optional_int32());
262 EXPECT_EQ(2, proto_.optional_int64());
263}
264
265TEST_F(TextFormatTest, OptionalColon) {
266 // Test that we can place a ':' after the field name of a nested message,
267 // even though we don't have to.
268
269 string parse_string = "optional_nested_message: { bb: 1}\n";
270
271 io::ArrayInputStream input_stream(parse_string.data(),
272 parse_string.size());
273
274 TextFormat::Parse(&input_stream, &proto_);
275
276 // Compare.
277 EXPECT_TRUE(proto_.has_optional_nested_message());
278 EXPECT_EQ(1, proto_.optional_nested_message().bb());
279}
280
281// Some platforms (e.g. Windows) insist on padding the exponent to three
282// digits when one or two would be just fine.
283static string RemoveRedundantZeros(string text) {
284 text = StringReplace(text, "e+0", "e+", true);
285 text = StringReplace(text, "e-0", "e-", true);
286 return text;
287}
288
289TEST_F(TextFormatTest, PrintExotic) {
290 unittest::TestAllTypes message;
291
292 // Note: In C, a negative integer literal is actually the unary negation
293 // operator being applied to a positive integer literal, and
294 // 9223372036854775808 is outside the range of int64. However, it is not
295 // outside the range of uint64. Confusingly, this means that everything
296 // works if we make the literal unsigned, even though we are negating it.
297 message.add_repeated_int64(-GOOGLE_ULONGLONG(9223372036854775808));
298 message.add_repeated_uint64(GOOGLE_ULONGLONG(18446744073709551615));
299 message.add_repeated_double(123.456);
300 message.add_repeated_double(1.23e21);
301 message.add_repeated_double(1.23e-18);
302 message.add_repeated_double(std::numeric_limits<double>::infinity());
303 message.add_repeated_double(-std::numeric_limits<double>::infinity());
304 message.add_repeated_double(std::numeric_limits<double>::quiet_NaN());
305 message.add_repeated_string(string("\000\001\a\b\f\n\r\t\v\\\'\"", 12));
306
307 // Fun story: We used to use 1.23e22 instead of 1.23e21 above, but this
308 // seemed to trigger an odd case on MinGW/GCC 3.4.5 where GCC's parsing of
309 // the value differed from strtod()'s parsing. That is to say, the
310 // following assertion fails on MinGW:
311 // assert(1.23e22 == strtod("1.23e22", NULL));
312 // As a result, SimpleDtoa() would print the value as
313 // "1.2300000000000001e+22" to make sure strtod() produce the exact same
314 // result. Our goal is to test runtime parsing, not compile-time parsing,
315 // so this wasn't our problem. It was found that using 1.23e21 did not
316 // have this problem, so we switched to that instead.
317
318 EXPECT_EQ(
319 "repeated_int64: -9223372036854775808\n"
320 "repeated_uint64: 18446744073709551615\n"
321 "repeated_double: 123.456\n"
322 "repeated_double: 1.23e+21\n"
323 "repeated_double: 1.23e-18\n"
324 "repeated_double: inf\n"
325 "repeated_double: -inf\n"
326 "repeated_double: nan\n"
327 "repeated_string: \"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\'\\\"\"\n",
328 RemoveRedundantZeros(message.DebugString()));
329}
330
331TEST_F(TextFormatTest, PrintFloatPrecision) {
332 unittest::TestAllTypes message;
333
334 message.add_repeated_float(1.2);
335 message.add_repeated_float(1.23);
336 message.add_repeated_float(1.234);
337 message.add_repeated_float(1.2345);
338 message.add_repeated_float(1.23456);
339 message.add_repeated_float(1.2e10);
340 message.add_repeated_float(1.23e10);
341 message.add_repeated_float(1.234e10);
342 message.add_repeated_float(1.2345e10);
343 message.add_repeated_float(1.23456e10);
344 message.add_repeated_double(1.2);
345 message.add_repeated_double(1.23);
346 message.add_repeated_double(1.234);
347 message.add_repeated_double(1.2345);
348 message.add_repeated_double(1.23456);
349 message.add_repeated_double(1.234567);
350 message.add_repeated_double(1.2345678);
351 message.add_repeated_double(1.23456789);
352 message.add_repeated_double(1.234567898);
353 message.add_repeated_double(1.2345678987);
354 message.add_repeated_double(1.23456789876);
355 message.add_repeated_double(1.234567898765);
356 message.add_repeated_double(1.2345678987654);
357 message.add_repeated_double(1.23456789876543);
358 message.add_repeated_double(1.2e100);
359 message.add_repeated_double(1.23e100);
360 message.add_repeated_double(1.234e100);
361 message.add_repeated_double(1.2345e100);
362 message.add_repeated_double(1.23456e100);
363 message.add_repeated_double(1.234567e100);
364 message.add_repeated_double(1.2345678e100);
365 message.add_repeated_double(1.23456789e100);
366 message.add_repeated_double(1.234567898e100);
367 message.add_repeated_double(1.2345678987e100);
368 message.add_repeated_double(1.23456789876e100);
369 message.add_repeated_double(1.234567898765e100);
370 message.add_repeated_double(1.2345678987654e100);
371 message.add_repeated_double(1.23456789876543e100);
372
373 EXPECT_EQ(
374 "repeated_float: 1.2\n"
375 "repeated_float: 1.23\n"
376 "repeated_float: 1.234\n"
377 "repeated_float: 1.2345\n"
378 "repeated_float: 1.23456\n"
379 "repeated_float: 1.2e+10\n"
380 "repeated_float: 1.23e+10\n"
381 "repeated_float: 1.234e+10\n"
382 "repeated_float: 1.2345e+10\n"
383 "repeated_float: 1.23456e+10\n"
384 "repeated_double: 1.2\n"
385 "repeated_double: 1.23\n"
386 "repeated_double: 1.234\n"
387 "repeated_double: 1.2345\n"
388 "repeated_double: 1.23456\n"
389 "repeated_double: 1.234567\n"
390 "repeated_double: 1.2345678\n"
391 "repeated_double: 1.23456789\n"
392 "repeated_double: 1.234567898\n"
393 "repeated_double: 1.2345678987\n"
394 "repeated_double: 1.23456789876\n"
395 "repeated_double: 1.234567898765\n"
396 "repeated_double: 1.2345678987654\n"
397 "repeated_double: 1.23456789876543\n"
398 "repeated_double: 1.2e+100\n"
399 "repeated_double: 1.23e+100\n"
400 "repeated_double: 1.234e+100\n"
401 "repeated_double: 1.2345e+100\n"
402 "repeated_double: 1.23456e+100\n"
403 "repeated_double: 1.234567e+100\n"
404 "repeated_double: 1.2345678e+100\n"
405 "repeated_double: 1.23456789e+100\n"
406 "repeated_double: 1.234567898e+100\n"
407 "repeated_double: 1.2345678987e+100\n"
408 "repeated_double: 1.23456789876e+100\n"
409 "repeated_double: 1.234567898765e+100\n"
410 "repeated_double: 1.2345678987654e+100\n"
411 "repeated_double: 1.23456789876543e+100\n",
412 RemoveRedundantZeros(message.DebugString()));
413}
414
415
416TEST_F(TextFormatTest, AllowPartial) {
417 unittest::TestRequired message;
418 TextFormat::Parser parser;
419 parser.AllowPartialMessage(true);
420 EXPECT_TRUE(parser.ParseFromString("a: 1", &message));
421 EXPECT_EQ(1, message.a());
422 EXPECT_FALSE(message.has_b());
423 EXPECT_FALSE(message.has_c());
424}
425
426TEST_F(TextFormatTest, ParseExotic) {
427 unittest::TestAllTypes message;
428 ASSERT_TRUE(TextFormat::ParseFromString(
429 "repeated_int32: -1\n"
430 "repeated_int32: -2147483648\n"
431 "repeated_int64: -1\n"
432 "repeated_int64: -9223372036854775808\n"
433 "repeated_uint32: 4294967295\n"
434 "repeated_uint32: 2147483648\n"
435 "repeated_uint64: 18446744073709551615\n"
436 "repeated_uint64: 9223372036854775808\n"
437 "repeated_double: 123.0\n"
438 "repeated_double: 123.5\n"
439 "repeated_double: 0.125\n"
440 "repeated_double: 1.23E17\n"
441 "repeated_double: 1.235E+22\n"
442 "repeated_double: 1.235e-18\n"
443 "repeated_double: 123.456789\n"
444 "repeated_double: inf\n"
445 "repeated_double: Infinity\n"
446 "repeated_double: -inf\n"
447 "repeated_double: -Infinity\n"
448 "repeated_double: nan\n"
449 "repeated_double: NaN\n"
450 "repeated_string: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\"\n",
451 &message));
452
453 ASSERT_EQ(2, message.repeated_int32_size());
454 EXPECT_EQ(-1, message.repeated_int32(0));
455 // Note: In C, a negative integer literal is actually the unary negation
456 // operator being applied to a positive integer literal, and 2147483648 is
457 // outside the range of int32. However, it is not outside the range of
458 // uint32. Confusingly, this means that everything works if we make the
459 // literal unsigned, even though we are negating it.
460 EXPECT_EQ(-2147483648u, message.repeated_int32(1));
461
462 ASSERT_EQ(2, message.repeated_int64_size());
463 EXPECT_EQ(-1, message.repeated_int64(0));
464 // Note: In C, a negative integer literal is actually the unary negation
465 // operator being applied to a positive integer literal, and
466 // 9223372036854775808 is outside the range of int64. However, it is not
467 // outside the range of uint64. Confusingly, this means that everything
468 // works if we make the literal unsigned, even though we are negating it.
469 EXPECT_EQ(-GOOGLE_ULONGLONG(9223372036854775808), message.repeated_int64(1));
470
471 ASSERT_EQ(2, message.repeated_uint32_size());
472 EXPECT_EQ(4294967295u, message.repeated_uint32(0));
473 EXPECT_EQ(2147483648u, message.repeated_uint32(1));
474
475 ASSERT_EQ(2, message.repeated_uint64_size());
476 EXPECT_EQ(GOOGLE_ULONGLONG(18446744073709551615), message.repeated_uint64(0));
477 EXPECT_EQ(GOOGLE_ULONGLONG(9223372036854775808), message.repeated_uint64(1));
478
479 ASSERT_EQ(13, message.repeated_double_size());
480 EXPECT_EQ(123.0 , message.repeated_double(0));
481 EXPECT_EQ(123.5 , message.repeated_double(1));
482 EXPECT_EQ(0.125 , message.repeated_double(2));
483 EXPECT_EQ(1.23E17 , message.repeated_double(3));
484 EXPECT_EQ(1.235E22 , message.repeated_double(4));
485 EXPECT_EQ(1.235E-18 , message.repeated_double(5));
486 EXPECT_EQ(123.456789, message.repeated_double(6));
487 EXPECT_EQ(message.repeated_double(7), numeric_limits<double>::infinity());
488 EXPECT_EQ(message.repeated_double(8), numeric_limits<double>::infinity());
489 EXPECT_EQ(message.repeated_double(9), -numeric_limits<double>::infinity());
490 EXPECT_EQ(message.repeated_double(10), -numeric_limits<double>::infinity());
491 EXPECT_TRUE(IsNaN(message.repeated_double(11)));
492 EXPECT_TRUE(IsNaN(message.repeated_double(12)));
493
494 // Note: Since these string literals have \0's in them, we must explicitly
495 // pass their sizes to string's constructor.
496 ASSERT_EQ(1, message.repeated_string_size());
497 EXPECT_EQ(string("\000\001\a\b\f\n\r\t\v\\\'\"", 12),
498 message.repeated_string(0));
499}
500
501class TextFormatParserTest : public testing::Test {
502 protected:
503 void ExpectFailure(const string& input, const string& message, int line,
504 int col) {
505 unittest::TestAllTypes proto;
506 ExpectFailure(input, message, line, col, &proto);
507 }
508
509 void ExpectFailure(const string& input, const string& message, int line,
510 int col, Message* proto) {
511 TextFormat::Parser parser;
512 MockErrorCollector error_collector;
513 parser.RecordErrorsTo(&error_collector);
514 EXPECT_FALSE(parser.ParseFromString(input, proto));
515 EXPECT_EQ(SimpleItoa(line) + ":" + SimpleItoa(col) + ": " + message + "\n",
516 error_collector.text_);
517 }
518
519 // An error collector which simply concatenates all its errors into a big
520 // block of text which can be checked.
521 class MockErrorCollector : public io::ErrorCollector {
522 public:
523 MockErrorCollector() {}
524 ~MockErrorCollector() {}
525
526 string text_;
527
528 // implements ErrorCollector -------------------------------------
529 void AddError(int line, int column, const string& message) {
530 strings::SubstituteAndAppend(&text_, "$0:$1: $2\n",
531 line + 1, column + 1, message);
532 }
533 };
534};
535
536TEST_F(TextFormatParserTest, InvalidToken) {
537 ExpectFailure("optional_bool: true\n-5\n", "Expected identifier.",
538 2, 1);
539
540 ExpectFailure("optional_bool: true;\n", "Expected identifier.", 1, 20);
541 ExpectFailure("\"some string\"", "Expected identifier.", 1, 1);
542}
543
544TEST_F(TextFormatParserTest, InvalidFieldName) {
545 ExpectFailure(
546 "invalid_field: somevalue\n",
547 "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
548 "\"invalid_field\".",
549 1, 14);
550}
551
552TEST_F(TextFormatParserTest, InvalidCapitalization) {
553 // We require that group names be exactly as they appear in the .proto.
554 ExpectFailure(
555 "optionalgroup {\na: 15\n}\n",
556 "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
557 "\"optionalgroup\".",
558 1, 15);
559 ExpectFailure(
560 "OPTIONALgroup {\na: 15\n}\n",
561 "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
562 "\"OPTIONALgroup\".",
563 1, 15);
564 ExpectFailure(
565 "Optional_Double: 10.0\n",
566 "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
567 "\"Optional_Double\".",
568 1, 16);
569}
570
571TEST_F(TextFormatParserTest, InvalidFieldValues) {
572 // Invalid values for a double/float field.
573 ExpectFailure("optional_double: \"hello\"\n", "Expected double.", 1, 18);
574 ExpectFailure("optional_double: true\n", "Expected double.", 1, 18);
575 ExpectFailure("optional_double: !\n", "Expected double.", 1, 18);
576 ExpectFailure("optional_double {\n \n}\n", "Expected \":\", found \"{\".",
577 1, 17);
578
579 // Invalid values for a signed integer field.
580 ExpectFailure("optional_int32: \"hello\"\n", "Expected integer.", 1, 17);
581 ExpectFailure("optional_int32: true\n", "Expected integer.", 1, 17);
582 ExpectFailure("optional_int32: 4.5\n", "Expected integer.", 1, 17);
583 ExpectFailure("optional_int32: !\n", "Expected integer.", 1, 17);
584 ExpectFailure("optional_int32 {\n \n}\n", "Expected \":\", found \"{\".",
585 1, 16);
586 ExpectFailure("optional_int32: 0x80000000\n",
587 "Integer out of range.", 1, 17);
588 ExpectFailure("optional_int32: -0x80000001\n",
589 "Integer out of range.", 1, 18);
590 ExpectFailure("optional_int64: 0x8000000000000000\n",
591 "Integer out of range.", 1, 17);
592 ExpectFailure("optional_int64: -0x8000000000000001\n",
593 "Integer out of range.", 1, 18);
594
595 // Invalid values for an unsigned integer field.
596 ExpectFailure("optional_uint64: \"hello\"\n", "Expected integer.", 1, 18);
597 ExpectFailure("optional_uint64: true\n", "Expected integer.", 1, 18);
598 ExpectFailure("optional_uint64: 4.5\n", "Expected integer.", 1, 18);
599 ExpectFailure("optional_uint64: -5\n", "Expected integer.", 1, 18);
600 ExpectFailure("optional_uint64: !\n", "Expected integer.", 1, 18);
601 ExpectFailure("optional_uint64 {\n \n}\n", "Expected \":\", found \"{\".",
602 1, 17);
603 ExpectFailure("optional_uint32: 0x100000000\n",
604 "Integer out of range.", 1, 18);
605 ExpectFailure("optional_uint64: 0x10000000000000000\n",
606 "Integer out of range.", 1, 18);
607
608 // Invalid values for a boolean field.
609 ExpectFailure("optional_bool: \"hello\"\n", "Expected identifier.", 1, 16);
610 ExpectFailure("optional_bool: 5\n", "Expected identifier.", 1, 16);
611 ExpectFailure("optional_bool: -7.5\n", "Expected identifier.", 1, 16);
612 ExpectFailure("optional_bool: !\n", "Expected identifier.", 1, 16);
613
614 ExpectFailure(
615 "optional_bool: meh\n",
616 "Invalid value for boolean field \"optional_bool\". Value: \"meh\".",
617 2, 1);
618
619 ExpectFailure("optional_bool {\n \n}\n", "Expected \":\", found \"{\".",
620 1, 15);
621
622 // Invalid values for a string field.
623 ExpectFailure("optional_string: true\n", "Expected string.", 1, 18);
624 ExpectFailure("optional_string: 5\n", "Expected string.", 1, 18);
625 ExpectFailure("optional_string: -7.5\n", "Expected string.", 1, 18);
626 ExpectFailure("optional_string: !\n", "Expected string.", 1, 18);
627 ExpectFailure("optional_string {\n \n}\n", "Expected \":\", found \"{\".",
628 1, 17);
629
630 // Invalid values for an enumeration field.
631 ExpectFailure("optional_nested_enum: \"hello\"\n", "Expected identifier.",
632 1, 23);
633
634 ExpectFailure("optional_nested_enum: 5\n", "Expected identifier.", 1, 23);
635 ExpectFailure("optional_nested_enum: -7.5\n", "Expected identifier.", 1, 23);
636 ExpectFailure("optional_nested_enum: !\n", "Expected identifier.", 1, 23);
637
638 ExpectFailure(
639 "optional_nested_enum: grah\n",
640 "Unknown enumeration value of \"grah\" for field "
641 "\"optional_nested_enum\".", 2, 1);
642
643 ExpectFailure(
644 "optional_nested_enum {\n \n}\n",
645 "Expected \":\", found \"{\".", 1, 22);
646}
647
648TEST_F(TextFormatParserTest, MessageDelimeters) {
649 // Non-matching delimeters.
650 ExpectFailure("OptionalGroup <\n \n}\n", "Expected \">\", found \"}\".",
651 3, 1);
652
653 // Invalid delimeters.
654 ExpectFailure("OptionalGroup [\n \n]\n", "Expected \"{\", found \"[\".",
655 1, 15);
656
657 // Unending message.
658 ExpectFailure("optional_nested_message {\n \nbb: 118\n",
659 "Expected identifier.",
660 4, 1);
661}
662
663TEST_F(TextFormatParserTest, UnknownExtension) {
664 // Non-matching delimeters.
665 ExpectFailure("[blahblah]: 123",
666 "Extension \"blahblah\" is not defined or is not an "
667 "extension of \"protobuf_unittest.TestAllTypes\".",
668 1, 11);
669}
670
671TEST_F(TextFormatParserTest, MissingRequired) {
672 unittest::TestRequired message;
673 ExpectFailure("a: 1",
674 "Message missing required fields: b, c",
675 0, 1, &message);
676}
677
678TEST_F(TextFormatParserTest, PrintErrorsToStderr) {
679 vector<string> errors;
680
681 {
682 ScopedMemoryLog log;
683 unittest::TestAllTypes proto;
684 EXPECT_FALSE(TextFormat::ParseFromString("no_such_field: 1", &proto));
685 errors = log.GetMessages(ERROR);
686 }
687
688 ASSERT_EQ(1, errors.size());
689 EXPECT_EQ("Error parsing text-format protobuf_unittest.TestAllTypes: "
690 "1:14: Message type \"protobuf_unittest.TestAllTypes\" has no field "
691 "named \"no_such_field\".",
692 errors[0]);
693}
694
695
696class TextFormatMessageSetTest : public testing::Test {
697 protected:
698 static const char proto_debug_string_[];
699};
700const char TextFormatMessageSetTest::proto_debug_string_[] =
701"message_set {\n"
702" [protobuf_unittest.TestMessageSetExtension1] {\n"
703" i: 23\n"
704" }\n"
705" [protobuf_unittest.TestMessageSetExtension2] {\n"
706" str: \"foo\"\n"
707" }\n"
708"}\n";
709
710
711TEST_F(TextFormatMessageSetTest, Serialize) {
712 protobuf_unittest::TestMessageSetContainer proto;
713 protobuf_unittest::TestMessageSetExtension1* item_a =
714 proto.mutable_message_set()->MutableExtension(
715 protobuf_unittest::TestMessageSetExtension1::message_set_extension);
716 item_a->set_i(23);
717 protobuf_unittest::TestMessageSetExtension2* item_b =
718 proto.mutable_message_set()->MutableExtension(
719 protobuf_unittest::TestMessageSetExtension2::message_set_extension);
720 item_b->set_str("foo");
721 EXPECT_EQ(proto_debug_string_, proto.DebugString());
722}
723
724TEST_F(TextFormatMessageSetTest, Deserialize) {
725 protobuf_unittest::TestMessageSetContainer proto;
726 ASSERT_TRUE(TextFormat::ParseFromString(proto_debug_string_, &proto));
727 EXPECT_EQ(23, proto.message_set().GetExtension(
728 protobuf_unittest::TestMessageSetExtension1::message_set_extension).i());
729 EXPECT_EQ("foo", proto.message_set().GetExtension(
730 protobuf_unittest::TestMessageSetExtension2::message_set_extension).str());
731
732 // Ensure that these are the only entries present.
733 vector<const FieldDescriptor*> descriptors;
734 proto.message_set().GetReflection()->ListFields(&descriptors);
735 EXPECT_EQ(2, descriptors.size());
736}
737
738} // namespace
739} // namespace protobuf
740
741} // namespace google